补齐画板视频封面持久化
生成画板视频时截取首帧并上传为封面 将视频生成结果写入素材库并保留 thumbnailSrc 同步后端契约、SpacetimeDB 绑定、前端素材库和画布层映射 补充相关测试与文档说明
This commit is contained in:
@@ -1097,6 +1097,18 @@ describe('editorProjectClient', () => {
|
||||
taskId: 'video-task-1',
|
||||
durationSeconds: 5,
|
||||
resolution: '480p',
|
||||
thumbnailSrc: '/generated-editor-videos/video-task-1/cover.png',
|
||||
asset: {
|
||||
assetId: 'asset-video-1',
|
||||
folderId: 'user-1:asset-folder:project',
|
||||
label: '生成视频 1',
|
||||
imageSrc: '/generated-editor-videos/video-task-1/preview.mp4',
|
||||
thumbnailSrc: '/generated-editor-videos/video-task-1/cover.png',
|
||||
width: 1280,
|
||||
height: 720,
|
||||
sourceType: 'generated',
|
||||
assetKind: 'video',
|
||||
},
|
||||
});
|
||||
|
||||
const result = await generateEditorVideo({
|
||||
@@ -1107,9 +1119,18 @@ describe('editorProjectClient', () => {
|
||||
resolution: '480p',
|
||||
mode: 'std',
|
||||
sound: 'off',
|
||||
assetFolderId: 'project',
|
||||
assetLabel: '生成视频 1',
|
||||
});
|
||||
|
||||
expect(result.taskId).toBe('video-task-1');
|
||||
expect(result.thumbnailSrc).toBe(
|
||||
'/generated-editor-videos/video-task-1/cover.png',
|
||||
);
|
||||
expect(result.asset?.assetId).toBe('asset-video-1');
|
||||
expect(result.asset?.thumbnailSrc).toBe(
|
||||
'/generated-editor-videos/video-task-1/cover.png',
|
||||
);
|
||||
expect(requestJsonMock).toHaveBeenCalledWith(
|
||||
'/api/editor/videos/generations',
|
||||
expect.objectContaining({
|
||||
@@ -1124,6 +1145,8 @@ describe('editorProjectClient', () => {
|
||||
mode: 'std',
|
||||
sound: 'off',
|
||||
webSearchEnabled: true,
|
||||
assetFolderId: 'project',
|
||||
assetLabel: '生成视频 1',
|
||||
}),
|
||||
}),
|
||||
'生成视频失败',
|
||||
|
||||
@@ -97,6 +97,7 @@ export type EditorAssetSnapshot = {
|
||||
folderId: string;
|
||||
label: string;
|
||||
imageSrc: string;
|
||||
thumbnailSrc?: string | null;
|
||||
objectKey?: string | null;
|
||||
assetObjectId?: string | null;
|
||||
width: number;
|
||||
@@ -329,10 +330,13 @@ export type EditorVideoGenerationInput = {
|
||||
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;
|
||||
@@ -343,8 +347,10 @@ export type EditorVideoGenerationResult = {
|
||||
model: string;
|
||||
provider: string;
|
||||
taskId: string;
|
||||
durationSeconds: number;
|
||||
priceMudPoints?: number;
|
||||
project?: EditorProjectSnapshot | null;
|
||||
asset?: EditorAssetSnapshot | null;
|
||||
queueState?: ExternalGenerationJobStatusRecord | null;
|
||||
};
|
||||
|
||||
@@ -912,6 +918,8 @@ export async function generateEditorVideo(input: EditorVideoGenerationInput) {
|
||||
? { sourceResourceId: input.sourceResourceId }
|
||||
: {}),
|
||||
...(input.assetKind ? { assetKind: input.assetKind } : {}),
|
||||
...(input.assetFolderId ? { assetFolderId: input.assetFolderId } : {}),
|
||||
...(input.assetLabel ? { assetLabel: input.assetLabel } : {}),
|
||||
}),
|
||||
'生成视频失败',
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user