Files
Genarrative/src/services/image-editor/editorProjectClient.ts
T
kdletters 63790e22ef 补齐画板视频封面持久化
生成画板视频时截取首帧并上传为封面

将视频生成结果写入素材库并保留 thumbnailSrc

同步后端契约、SpacetimeDB 绑定、前端素材库和画布层映射

补充相关测试与文档说明
2026-06-28 00:22:59 +08:00

980 lines
28 KiB
TypeScript

import { requestJson } from '../apiClient';
import type { ExternalGenerationJobStatusRecord } from '../../../packages/shared/src/contracts/externalGeneration';
import { EDITOR_REQUEST_RETRY_OPTIONS } from './editorRetryOptions';
const EDITOR_PROJECT_API_BASE = '/api/editor/projects';
const EDITOR_ASSET_API_BASE = '/api/editor/assets';
const EDITOR_SHOWCASE_RESOURCE_API = '/api/editor/showcase/resources';
const EDITOR_PROJECT_RESOURCE_API_BASE = '/api/editor/project-resources';
const EDITOR_IMAGE_GENERATION_API = '/api/editor/images/generations';
const EDITOR_IMAGE_EDIT_API = '/api/editor/images/edits';
const EDITOR_ICON_SPRITESHEET_GENERATION_API =
'/api/editor/icon-spritesheets/generations';
const EDITOR_UI_DESIGN_ASSET_EXTRACTION_API =
'/api/editor/ui-designs/assets/extractions';
const EDITOR_CHARACTER_ANIMATION_GENERATION_API =
'/api/editor/character-animations/generations';
const EDITOR_VIDEO_GENERATION_API = '/api/editor/videos/generations';
const EDITOR_SOUND_EFFECT_GENERATION_API =
'/api/editor/audios/sound-effects/generations';
const EDITOR_BACKGROUND_MUSIC_GENERATION_API =
'/api/editor/audios/background-music/generations';
const EDITOR_GENERATION_PRICING_API = '/api/editor/generation-pricing';
const EDITOR_IMAGE_MODEL_NANOBANANA2 = 'gemini-3.1-flash-image-preview';
const DEFAULT_PROJECT_TITLE = '未命名画布';
export type EditorCanvasViewport = {
x: number;
y: number;
scale: number;
};
export type EditorProjectLayerSnapshot = Record<string, unknown> & {
layerId: string;
resourceId: string;
};
export type EditorAssetGenerationInputField = {
title: string;
value: string;
};
export type EditorAssetGenerationInputReference = {
title: string;
label: string;
refType: 'project-resource' | 'asset';
refId: string;
};
export type EditorAssetGenerationInputs = {
fields: EditorAssetGenerationInputField[];
references: EditorAssetGenerationInputReference[];
};
export type EditorProjectResourceSourceType =
| 'uploaded'
| 'generated'
| 'mock_generated';
export type EditorProjectResourceSnapshot = {
resourceId: string;
projectId: string;
ownerUserId?: string | null;
authorDisplayName?: string | null;
authorPublicUserCode?: string | null;
imageSrc: string;
objectKey?: string | null;
assetObjectId?: string | null;
width: number;
height: number;
sourceType: EditorProjectResourceSourceType;
prompt?: string | null;
actualPrompt?: string | null;
model?: string | null;
provider?: string | null;
taskId?: string | null;
durationSeconds?: number | null;
sourceResourceId?: string | null;
assetKind?: string | null;
generationInputs?: EditorAssetGenerationInputs | null;
publicShowcaseEnabled?: boolean;
createdAt?: string;
updatedAt?: string;
};
export type EditorAssetFolderSnapshot = {
folderId: string;
label: string;
sortOrder: number;
collapsed: boolean;
systemDefault: boolean;
createdAt?: string;
updatedAt?: string;
};
export type EditorAssetSnapshot = {
assetId: string;
folderId: string;
label: string;
imageSrc: string;
thumbnailSrc?: string | null;
objectKey?: string | null;
assetObjectId?: string | null;
width: number;
height: number;
sourceType: EditorProjectResourceSourceType;
prompt?: string | null;
actualPrompt?: string | null;
model?: string | null;
provider?: string | null;
taskId?: string | null;
durationSeconds?: number | null;
sourceResourceId?: string | null;
assetKind?: string | null;
generationInputs?: EditorAssetGenerationInputs | null;
publicShowcaseEnabled?: boolean | null;
createdAt?: string;
updatedAt?: string;
};
export type EditorAssetLibrarySnapshot = {
folders: EditorAssetFolderSnapshot[];
assets: EditorAssetSnapshot[];
};
export type EditorImageGenerationInput = {
prompt: string;
size?: string;
kind?:
| 'spec'
| 'character'
| 'quick-edit'
| 'ui-design'
| 'publication-material';
model?: string;
aspectRatio?: string;
imageSize?: string;
referenceImageSrcs?: string[];
projectId?: string | null;
assetKind?: string | null;
generationInputs?: EditorAssetGenerationInputs | null;
assetFolderId?: string | null;
assetLabel?: string | null;
sourceResourceId?: string | null;
canvasCompletion?: EditorCanvasGenerationCompletionInput | null;
};
export type EditorCanvasGenerationCompletionInput = {
dialogId?: string;
title: string;
placeholder: {
x: number;
y: number;
width: number;
height: number;
originalWidth: number;
originalHeight: number;
};
};
export type EditorIconSpritesheetGenerationInput = {
referenceImageSrc: string;
referenceImageSrcs?: string[];
iconDescriptions: string[];
model?: string;
aspectRatio?: string;
imageSize?: string;
projectId?: string | null;
generationInputs?: EditorAssetGenerationInputs | null;
assetFolderId?: string | null;
canvasCompletion?: EditorCanvasGenerationCompletionInput | null;
};
export type EditorUiDesignAssetExtractionInput = {
sourceImageSrc: string;
model?: string;
referenceImageSrcs?: string[];
aspectRatio?: string;
imageSize?: string;
projectId?: string | null;
generationInputs?: EditorAssetGenerationInputs | null;
assetFolderId?: string | null;
spritesheetLabel?: string | null;
canvasCompletion?: EditorCanvasGenerationCompletionInput | null;
};
export type EditorImageEditInput = {
prompt: string;
sourceImageSrc: string;
size?: string;
model?: string;
projectId?: string | null;
assetKind?: string | null;
generationInputs?: EditorAssetGenerationInputs | null;
assetFolderId?: string | null;
assetLabel?: string | null;
sourceResourceId?: string | null;
canvasCompletion?: EditorCanvasGenerationCompletionInput | null;
};
export type EditorImageGenerationResult = {
imageSrc: string;
objectKey?: string | null;
assetObjectId?: string | null;
width: number;
height: number;
sourceType: 'generated';
prompt: string;
actualPrompt?: string | null;
model: string;
provider: string;
taskId: string;
resource?: EditorProjectResourceSnapshot | null;
asset?: EditorAssetSnapshot | null;
project?: EditorProjectSnapshot | null;
queueState?: ExternalGenerationJobStatusRecord | null;
};
export type EditorIconSpritesheetIconResult = {
name: string;
imageSrc: string;
width: number;
height: number;
resource?: EditorProjectResourceSnapshot | null;
asset?: EditorAssetSnapshot | null;
};
export type EditorIconSpritesheetGenerationResult = {
spritesheetImageSrc: string;
spritesheetWidth: number;
spritesheetHeight: number;
iconImageSrcs: EditorIconSpritesheetIconResult[];
prompt: string;
actualPrompt?: string | null;
model: string;
provider: string;
taskId: string;
priceMudPoints: number;
spritesheetResource?: EditorProjectResourceSnapshot | null;
spritesheetAsset?: EditorAssetSnapshot | null;
project?: EditorProjectSnapshot | null;
queueState?: ExternalGenerationJobStatusRecord | null;
};
export type EditorCharacterAnimationResolution = '480p' | '720p';
export type EditorCharacterAnimationRatio =
| 'same'
| '1:1'
| '4:3'
| '16:9'
| '9:16'
| '3:4';
export type EditorCharacterAnimationFrameCount = 32 | 40 | 48;
export type EditorCharacterAnimationDurationSeconds = 4 | 5 | 6;
export type EditorCharacterAnimationGenerationInput = {
sourceLayerId: string;
sourceImageSrc: string;
sourceWidth: number;
sourceHeight: number;
promptText: string;
resolution: EditorCharacterAnimationResolution;
ratio: EditorCharacterAnimationRatio;
frameCount: EditorCharacterAnimationFrameCount;
durationSeconds: EditorCharacterAnimationDurationSeconds;
model: 'seedance2.0-fast';
projectId?: string | null;
canvasCompletion?: EditorCanvasGenerationCompletionInput | null;
generationInputs?: EditorAssetGenerationInputs | null;
sourceResourceId?: string | null;
};
export type EditorCharacterAnimationFrameResult = {
frameIndex: number;
imageSrc: string;
objectKey?: string | null;
assetObjectId?: string | null;
width: number;
height: number;
};
export type EditorCharacterAnimationGenerationResult = {
taskId: string;
model: 'seedance2.0-fast';
prompt: string;
previewVideoPath: string;
frames: EditorCharacterAnimationFrameResult[];
frameCount: number;
durationSeconds: number;
fps: number;
priceMudPoints: number;
project?: EditorProjectSnapshot | null;
queueState?: ExternalGenerationJobStatusRecord | null;
};
export type EditorVideoModel =
| 'seedance2.0'
| 'seedance2.0-fast'
| 'kling3.0'
| 'kling3.0-omni'
| 'veo3.1'
| 'veo3.1-fast';
export type EditorVideoResolution = '480p' | '720p' | '1080p';
export type EditorVideoSoundMode = 'on' | 'off';
export type EditorVideoAspectRatio =
| '16:9'
| '9:16'
| '1:1'
| '4:3'
| '3:4'
| '21:9';
export type EditorVideoGenerationInput = {
prompt: string;
model: EditorVideoModel;
aspectRatio: EditorVideoAspectRatio;
durationSeconds: number;
resolution: EditorVideoResolution;
mode: 'std';
sound: EditorVideoSoundMode;
webSearchEnabled?: boolean;
referenceImageSrcs?: string[];
referenceVideoSrcs?: string[];
referenceAudioSrcs?: string[];
projectId?: string | null;
canvasCompletion?: EditorCanvasGenerationCompletionInput | null;
generationInputs?: EditorAssetGenerationInputs | null;
sourceResourceId?: string | null;
assetKind?: string | null;
assetFolderId?: string | null;
assetLabel?: string | null;
};
export type EditorVideoGenerationResult = {
videoSrc: string;
thumbnailSrc?: string | null;
objectKey?: string | null;
assetObjectId?: string | null;
width: number;
height: number;
sourceType: 'generated';
prompt: string;
actualPrompt?: string | null;
model: string;
provider: string;
taskId: string;
durationSeconds: number;
priceMudPoints?: number;
project?: EditorProjectSnapshot | null;
asset?: EditorAssetSnapshot | null;
queueState?: ExternalGenerationJobStatusRecord | null;
};
export type EditorSoundEffectGenerationInput = {
prompt: string;
model: 'audio1.0';
duration: number;
projectId?: string | null;
canvasCompletion?: EditorCanvasGenerationCompletionInput | null;
generationInputs?: EditorAssetGenerationInputs | null;
};
export type EditorBackgroundMusicGenerationInput = {
gptDescriptionPrompt: string;
makeInstrumental: true;
projectId?: string | null;
canvasCompletion?: EditorCanvasGenerationCompletionInput | null;
generationInputs?: EditorAssetGenerationInputs | null;
};
export type EditorAudioGenerationResult = {
audioSrc: string;
objectKey?: string | null;
assetObjectId?: string | null;
width: number;
height: number;
sourceType: 'generated';
prompt: string;
actualPrompt?: string | null;
model: string;
provider: string;
taskId: string;
priceMudPoints: number;
audioKind: 'sound-effect' | 'background-music';
durationSeconds?: number | null;
project?: EditorProjectSnapshot | null;
queueState?: ExternalGenerationJobStatusRecord | null;
};
export type EditorGenerationPricingUnit = 'perGeneration' | 'perSecond';
export type EditorGenerationModelPricing = {
unit: EditorGenerationPricingUnit;
price?: number;
prices?: Record<string, number>;
};
export type EditorGenerationPricingConfig = {
models: Record<string, EditorGenerationModelPricing>;
};
export type EditorProjectSnapshot = {
projectId: string;
title: string;
canvas?: EditorCanvasSnapshot;
viewport: EditorCanvasViewport;
layers: EditorProjectLayerSnapshot[];
resources: EditorProjectResourceSnapshot[];
updatedAt: string;
};
export type EditorCanvasSnapshot = {
canvasId: string;
projectId: string;
title: string;
viewport: EditorCanvasViewport;
layers: EditorProjectLayerSnapshot[];
createdAt?: string;
updatedAt: string;
};
export type EditorProjectCreateInput = {
title?: string;
};
export type EditorProjectLayoutSaveInput = {
viewport: EditorCanvasViewport;
layers: EditorProjectLayerSnapshot[];
};
export type EditorProjectLayoutSaveResult = {
projectId: string;
canvasId: string;
updatedAt: string;
};
export type EditorProjectResourceCreateInput = {
imageSrc: string;
objectKey?: string | null;
assetObjectId?: string | null;
width: number;
height: number;
sourceType: EditorProjectResourceSourceType;
prompt?: string | null;
actualPrompt?: string | null;
model?: string | null;
provider?: string | null;
taskId?: string | null;
durationSeconds?: number | null;
sourceResourceId?: string | null;
assetKind?: string | null;
generationInputs?: EditorAssetGenerationInputs | null;
};
export type EditorAssetCreateInput = {
folderId: string;
label: string;
imageSrc: string;
objectKey?: string | null;
assetObjectId?: string | null;
width: number;
height: number;
sourceType: EditorProjectResourceSourceType;
prompt?: string | null;
actualPrompt?: string | null;
model?: string | null;
provider?: string | null;
taskId?: string | null;
durationSeconds?: number | null;
assetKind?: string | null;
generationInputs?: EditorAssetGenerationInputs | null;
};
export type EditorAssetUpdateInput = {
label?: string;
folderId?: string;
};
type EditorProjectResponse = {
project: EditorProjectSnapshot;
};
type EditorProjectLayoutSaveResponse = EditorProjectLayoutSaveResult;
type EditorProjectRecentResponse = {
project: EditorProjectSnapshot | null;
};
type EditorProjectResourceResponse = {
resource: EditorProjectResourceSnapshot;
};
type EditorProjectResourceListResponse = {
resources: EditorProjectResourceSnapshot[];
};
type EditorAssetLibraryResponse = {
library: EditorAssetLibrarySnapshot;
};
type EditorAssetFolderResponse = {
folder: EditorAssetFolderSnapshot;
};
type EditorAssetFolderDeleteResponse = {
library: EditorAssetLibrarySnapshot;
};
type EditorAssetResponse = {
asset: EditorAssetSnapshot;
};
type EditorImageGenerationResponse = EditorImageGenerationResult;
type EditorIconSpritesheetGenerationResponse =
EditorIconSpritesheetGenerationResult;
type EditorVideoGenerationResponse = EditorVideoGenerationResult;
type EditorAudioGenerationResponse = EditorAudioGenerationResult;
function jsonRequest(method: 'POST' | 'PATCH', body: Record<string, unknown>) {
return {
method,
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body),
};
}
export async function listEditorProjects() {
const response = await requestJson<{ projects: EditorProjectSnapshot[] }>(
EDITOR_PROJECT_API_BASE,
{ method: 'GET' },
'读取图片画布工程列表失败',
);
return response.projects;
}
export async function listPublicEditorProjectResources() {
const response = await requestJson<EditorProjectResourceListResponse>(
EDITOR_SHOWCASE_RESOURCE_API,
{ method: 'GET' },
'读取陶泥儿精选素材失败',
{
skipAuth: true,
skipRefresh: true,
notifyAuthStateChange: false,
clearAuthOnUnauthorized: false,
},
);
return response.resources;
}
export async function loadRecentEditorProject() {
return requestJson<EditorProjectRecentResponse>(
`${EDITOR_PROJECT_API_BASE}/recent`,
{ method: 'GET' },
'读取图片画布工程失败',
);
}
export async function createEditorProject(
input: EditorProjectCreateInput = {},
) {
const response = await requestJson<EditorProjectResponse>(
EDITOR_PROJECT_API_BASE,
jsonRequest('POST', {
title: input.title?.trim() || DEFAULT_PROJECT_TITLE,
}),
'创建图片画布工程失败',
);
return response.project;
}
export async function loadOrCreateRecentEditorProject() {
const response = await loadRecentEditorProject();
if (response.project) {
return response.project;
}
return createEditorProject({ title: DEFAULT_PROJECT_TITLE });
}
export async function loadEditorGenerationPricing() {
return requestJson<EditorGenerationPricingConfig>(
EDITOR_GENERATION_PRICING_API,
{ method: 'GET' },
'读取模型定价失败',
{
skipAuth: true,
skipRefresh: true,
notifyAuthStateChange: false,
clearAuthOnUnauthorized: false,
},
);
}
export async function loadEditorProject(projectId: string) {
const response = await requestJson<EditorProjectResponse>(
`${EDITOR_PROJECT_API_BASE}/${encodeURIComponent(projectId)}`,
{ method: 'GET' },
'读取图片画布工程失败',
);
return response.project;
}
export async function renameEditorProject(projectId: string, title: string) {
const response = await requestJson<EditorProjectResponse>(
`${EDITOR_PROJECT_API_BASE}/${encodeURIComponent(projectId)}/metadata`,
jsonRequest('PATCH', { title }),
'重命名图片画布工程失败',
);
return response.project;
}
export async function deleteEditorProject(projectId: string) {
const response = await requestJson<{ deletedProjectId: string }>(
`${EDITOR_PROJECT_API_BASE}/${encodeURIComponent(projectId)}`,
{ method: 'DELETE' },
'删除图片画布工程失败',
);
return response.deletedProjectId;
}
export async function saveEditorProjectLayout(
projectId: string,
input: EditorProjectLayoutSaveInput,
) {
return requestJson<EditorProjectLayoutSaveResponse>(
`${EDITOR_PROJECT_API_BASE}/${encodeURIComponent(projectId)}`,
jsonRequest('PATCH', {
viewport: input.viewport,
layers: input.layers,
}),
'保存图片画布工程失败',
);
}
export async function createEditorProjectResource(
projectId: string,
input: EditorProjectResourceCreateInput,
) {
const response = await requestJson<EditorProjectResourceResponse>(
`${EDITOR_PROJECT_API_BASE}/${encodeURIComponent(projectId)}/resources`,
jsonRequest('POST', { ...input }),
'创建图片画布资源失败',
);
return response.resource;
}
export async function updateEditorProjectResourceShowcase(
resourceId: string,
publicShowcaseEnabled: boolean,
) {
const response = await requestJson<EditorProjectResourceResponse>(
`${EDITOR_PROJECT_RESOURCE_API_BASE}/${encodeURIComponent(resourceId)}/showcase`,
jsonRequest('PATCH', { publicShowcaseEnabled }),
'更新素材公开展示状态失败',
);
return response.resource;
}
export async function loadEditorAssetLibrary() {
const response = await requestJson<EditorAssetLibraryResponse>(
`${EDITOR_ASSET_API_BASE}/library`,
{ method: 'GET' },
'读取图片画布素材库失败',
);
return response.library;
}
export async function createEditorAssetFolder(
label: string,
sortOrder?: number,
) {
const response = await requestJson<EditorAssetFolderResponse>(
`${EDITOR_ASSET_API_BASE}/folders`,
jsonRequest('POST', { label, sortOrder }),
'创建图片画布素材文件夹失败',
);
return response.folder;
}
export async function updateEditorAssetFolder(
folderId: string,
input: { label?: string; collapsed?: boolean },
) {
const response = await requestJson<EditorAssetFolderResponse>(
`${EDITOR_ASSET_API_BASE}/folders/${encodeURIComponent(folderId)}`,
jsonRequest('PATCH', input),
'更新图片画布素材文件夹失败',
);
return response.folder;
}
export async function deleteEditorAssetFolder(folderId: string) {
const response = await requestJson<EditorAssetFolderDeleteResponse>(
`${EDITOR_ASSET_API_BASE}/folders/${encodeURIComponent(folderId)}`,
{ method: 'DELETE' },
'删除图片画布素材文件夹失败',
);
return response.library;
}
export async function createEditorAsset(input: EditorAssetCreateInput) {
const response = await requestJson<EditorAssetResponse>(
EDITOR_ASSET_API_BASE,
jsonRequest('POST', input),
'创建图片画布素材失败',
);
return response.asset;
}
export async function updateEditorAsset(
assetId: string,
input: EditorAssetUpdateInput,
) {
const response = await requestJson<EditorAssetResponse>(
`${EDITOR_ASSET_API_BASE}/${encodeURIComponent(assetId)}`,
jsonRequest('PATCH', input),
'更新图片画布素材失败',
);
return response.asset;
}
export async function deleteEditorAsset(assetId: string) {
const response = await requestJson<EditorAssetResponse>(
`${EDITOR_ASSET_API_BASE}/${encodeURIComponent(assetId)}`,
{ method: 'DELETE' },
'删除图片画布素材失败',
);
return response.asset;
}
export async function generateEditorImage(input: EditorImageGenerationInput) {
return requestJson<EditorImageGenerationResponse>(
EDITOR_IMAGE_GENERATION_API,
jsonRequest('POST', {
prompt: input.prompt,
...(input.size ? { size: input.size } : {}),
...(input.kind ? { kind: input.kind } : {}),
...(input.model ? { model: input.model } : {}),
...(input.aspectRatio ? { aspectRatio: input.aspectRatio } : {}),
...(input.imageSize ? { imageSize: input.imageSize } : {}),
...(input.referenceImageSrcs?.length
? { referenceImageSrcs: input.referenceImageSrcs }
: {}),
...(input.projectId ? { projectId: input.projectId } : {}),
...(input.assetKind ? { assetKind: input.assetKind } : {}),
...(input.generationInputs
? { generationInputs: input.generationInputs }
: {}),
...(input.assetFolderId ? { assetFolderId: input.assetFolderId } : {}),
...(input.assetLabel ? { assetLabel: input.assetLabel } : {}),
...(input.sourceResourceId
? { sourceResourceId: input.sourceResourceId }
: {}),
...(input.canvasCompletion
? { canvasCompletion: input.canvasCompletion }
: {}),
}),
'生成图片失败',
{
timeoutMs: 1_200_000,
retry: EDITOR_REQUEST_RETRY_OPTIONS,
},
);
}
export async function generateEditorIconSpritesheet(
input: EditorIconSpritesheetGenerationInput,
) {
return requestJson<EditorIconSpritesheetGenerationResponse>(
EDITOR_ICON_SPRITESHEET_GENERATION_API,
jsonRequest('POST', {
referenceImageSrc: input.referenceImageSrc,
...(input.referenceImageSrcs?.length
? { referenceImageSrcs: input.referenceImageSrcs }
: {}),
iconDescriptions: input.iconDescriptions,
model: input.model?.trim() || EDITOR_IMAGE_MODEL_NANOBANANA2,
...(input.aspectRatio ? { aspectRatio: input.aspectRatio } : {}),
...(input.imageSize ? { imageSize: input.imageSize } : {}),
...(input.projectId ? { projectId: input.projectId } : {}),
...(input.generationInputs
? { generationInputs: input.generationInputs }
: {}),
...(input.assetFolderId ? { assetFolderId: input.assetFolderId } : {}),
...(input.canvasCompletion
? { canvasCompletion: input.canvasCompletion }
: {}),
}),
'生成图标素材失败',
{
timeoutMs: 1_200_000,
retry: EDITOR_REQUEST_RETRY_OPTIONS,
},
);
}
export async function extractEditorUiDesignAssets(
input: EditorUiDesignAssetExtractionInput,
) {
return requestJson<EditorIconSpritesheetGenerationResponse>(
EDITOR_UI_DESIGN_ASSET_EXTRACTION_API,
jsonRequest('POST', {
sourceImageSrc: input.sourceImageSrc,
...(input.model ? { model: input.model } : {}),
...(input.referenceImageSrcs?.length
? { referenceImageSrcs: input.referenceImageSrcs }
: {}),
...(input.projectId ? { projectId: input.projectId } : {}),
...(input.generationInputs
? { generationInputs: input.generationInputs }
: {}),
...(input.assetFolderId ? { assetFolderId: input.assetFolderId } : {}),
...(input.spritesheetLabel
? { spritesheetLabel: input.spritesheetLabel }
: {}),
...(input.aspectRatio ? { aspectRatio: input.aspectRatio } : {}),
...(input.imageSize ? { imageSize: input.imageSize } : {}),
...(input.canvasCompletion
? { canvasCompletion: input.canvasCompletion }
: {}),
}),
'提取UI设计图素材失败',
{
timeoutMs: 1_200_000,
retry: EDITOR_REQUEST_RETRY_OPTIONS,
},
);
}
export async function editEditorImage(input: EditorImageEditInput) {
return requestJson<EditorImageGenerationResponse>(
EDITOR_IMAGE_EDIT_API,
jsonRequest('POST', {
prompt: input.prompt,
sourceImageSrc: input.sourceImageSrc,
...(input.size ? { size: input.size } : {}),
...(input.model ? { model: input.model } : {}),
...(input.projectId ? { projectId: input.projectId } : {}),
...(input.assetKind ? { assetKind: input.assetKind } : {}),
...(input.generationInputs
? { generationInputs: input.generationInputs }
: {}),
...(input.assetFolderId ? { assetFolderId: input.assetFolderId } : {}),
...(input.assetLabel ? { assetLabel: input.assetLabel } : {}),
...(input.sourceResourceId
? { sourceResourceId: input.sourceResourceId }
: {}),
...(input.canvasCompletion
? { canvasCompletion: input.canvasCompletion }
: {}),
}),
'修改图片失败',
{
timeoutMs: 1_200_000,
retry: EDITOR_REQUEST_RETRY_OPTIONS,
},
);
}
export async function generateEditorCharacterAnimation(
input: EditorCharacterAnimationGenerationInput,
) {
return requestJson<EditorCharacterAnimationGenerationResult>(
EDITOR_CHARACTER_ANIMATION_GENERATION_API,
jsonRequest('POST', {
...input,
...(input.projectId ? { projectId: input.projectId } : {}),
...(input.canvasCompletion
? { canvasCompletion: input.canvasCompletion }
: {}),
...(input.generationInputs
? { generationInputs: input.generationInputs }
: {}),
...(input.sourceResourceId
? { sourceResourceId: input.sourceResourceId }
: {}),
}),
'生成角色动画失败',
{
timeoutMs: 1_200_000,
retry: EDITOR_REQUEST_RETRY_OPTIONS,
},
);
}
export async function generateEditorVideo(input: EditorVideoGenerationInput) {
return requestJson<EditorVideoGenerationResponse>(
EDITOR_VIDEO_GENERATION_API,
jsonRequest('POST', {
prompt: input.prompt,
model: input.model,
aspectRatio: input.aspectRatio,
durationSeconds: input.durationSeconds,
resolution: input.resolution,
mode: input.mode,
sound: input.sound,
webSearchEnabled: input.webSearchEnabled ?? true,
...(input.referenceImageSrcs?.length
? { referenceImageSrcs: input.referenceImageSrcs }
: {}),
...(input.referenceVideoSrcs?.length
? { referenceVideoSrcs: input.referenceVideoSrcs }
: {}),
...(input.referenceAudioSrcs?.length
? { referenceAudioSrcs: input.referenceAudioSrcs }
: {}),
...(input.projectId ? { projectId: input.projectId } : {}),
...(input.canvasCompletion
? { canvasCompletion: input.canvasCompletion }
: {}),
...(input.generationInputs
? { generationInputs: input.generationInputs }
: {}),
...(input.sourceResourceId
? { sourceResourceId: input.sourceResourceId }
: {}),
...(input.assetKind ? { assetKind: input.assetKind } : {}),
...(input.assetFolderId ? { assetFolderId: input.assetFolderId } : {}),
...(input.assetLabel ? { assetLabel: input.assetLabel } : {}),
}),
'生成视频失败',
{
timeoutMs: 1_200_000,
retry: EDITOR_REQUEST_RETRY_OPTIONS,
},
);
}
export async function generateEditorSoundEffect(
input: EditorSoundEffectGenerationInput,
) {
return requestJson<EditorAudioGenerationResponse>(
EDITOR_SOUND_EFFECT_GENERATION_API,
jsonRequest('POST', {
prompt: input.prompt,
model: input.model,
duration: input.duration,
...(input.projectId ? { projectId: input.projectId } : {}),
...(input.canvasCompletion
? { canvasCompletion: input.canvasCompletion }
: {}),
...(input.generationInputs
? { generationInputs: input.generationInputs }
: {}),
}),
'生成游戏音效失败',
{
timeoutMs: 1_200_000,
retry: EDITOR_REQUEST_RETRY_OPTIONS,
},
);
}
export async function generateEditorBackgroundMusic(
input: EditorBackgroundMusicGenerationInput,
) {
return requestJson<EditorAudioGenerationResponse>(
EDITOR_BACKGROUND_MUSIC_GENERATION_API,
jsonRequest('POST', {
gptDescriptionPrompt: input.gptDescriptionPrompt,
makeInstrumental: input.makeInstrumental,
...(input.projectId ? { projectId: input.projectId } : {}),
...(input.canvasCompletion
? { canvasCompletion: input.canvasCompletion }
: {}),
...(input.generationInputs
? { generationInputs: input.generationInputs }
: {}),
}),
'生成游戏背景音乐失败',
{
timeoutMs: 1_200_000,
retry: EDITOR_REQUEST_RETRY_OPTIONS,
},
);
}