|
|
@@ -109,29 +109,26 @@ export async function parseText(
|
|
|
const scenes: Scene[] = [];
|
|
|
let sceneIndex = 0;
|
|
|
|
|
|
- // Cover scene (optional)
|
|
|
- if (videoInput.cover) {
|
|
|
- scenes.push({
|
|
|
- id: "cover",
|
|
|
- index: sceneIndex++,
|
|
|
- sceneType: "cover",
|
|
|
- narration: "",
|
|
|
- title: videoInput.title,
|
|
|
- keyframes: videoInput.cover.keyframes ?? [],
|
|
|
- images: [
|
|
|
- ...(videoInput.cover.imagePath
|
|
|
- ? [{ path: videoInput.cover.imagePath }]
|
|
|
- : []),
|
|
|
- ...(videoInput.cover.imageUrl
|
|
|
- ? [{ url: videoInput.cover.imageUrl }]
|
|
|
- : []),
|
|
|
- ...(videoInput.cover.imageQuery
|
|
|
- ? [{ query: videoInput.cover.imageQuery }]
|
|
|
- : []),
|
|
|
- ],
|
|
|
- backgroundQuery: videoInput.cover.imageQuery,
|
|
|
- });
|
|
|
- }
|
|
|
+ // Cover scene — always present. Use cover.keyframes/images if the user/LLM
|
|
|
+ // provided them, otherwise fall back to an empty cover driven by the
|
|
|
+ // top-level title/subtitle. Default 1s so it flashes briefly without
|
|
|
+ // pushing back the real content.
|
|
|
+ const coverInput = videoInput.cover;
|
|
|
+ scenes.push({
|
|
|
+ id: "cover",
|
|
|
+ index: sceneIndex++,
|
|
|
+ sceneType: "cover",
|
|
|
+ narration: "",
|
|
|
+ title: videoInput.title,
|
|
|
+ keyframes: coverInput?.keyframes ?? [],
|
|
|
+ images: [
|
|
|
+ ...(coverInput?.imagePath ? [{ path: coverInput.imagePath }] : []),
|
|
|
+ ...(coverInput?.imageUrl ? [{ url: coverInput.imageUrl }] : []),
|
|
|
+ ...(coverInput?.imageQuery ? [{ query: coverInput.imageQuery }] : []),
|
|
|
+ ],
|
|
|
+ backgroundQuery: coverInput?.imageQuery,
|
|
|
+ duration: 1,
|
|
|
+ });
|
|
|
|
|
|
// Content scenes
|
|
|
for (const s of videoInput.scenes) {
|