mulmocast 0.0.9 → 0.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/README.md +20 -3
  2. package/assets/templates/akira_comic.json +2 -2
  3. package/assets/templates/drslump_comic.json +2 -2
  4. package/assets/templates/ghibli_comic.json +2 -2
  5. package/assets/templates/ghost_comic.json +2 -2
  6. package/assets/templates/onepiece_comic.json +2 -2
  7. package/assets/templates/portrait_movie.json +28 -0
  8. package/assets/templates/realistic_movie.json +28 -0
  9. package/assets/templates/shorts.json +18 -0
  10. package/lib/actions/audio.d.ts +2 -1
  11. package/lib/actions/audio.js +8 -3
  12. package/lib/actions/captions.js +2 -2
  13. package/lib/actions/images.d.ts +2 -1
  14. package/lib/actions/images.js +68 -32
  15. package/lib/actions/movie.js +10 -6
  16. package/lib/actions/translate.d.ts +2 -1
  17. package/lib/actions/translate.js +8 -3
  18. package/lib/agents/combine_audio_files_agent.js +4 -0
  19. package/lib/agents/image_google_agent.d.ts +4 -1
  20. package/lib/agents/image_google_agent.js +3 -2
  21. package/lib/agents/image_openai_agent.d.ts +5 -3
  22. package/lib/agents/image_openai_agent.js +29 -4
  23. package/lib/agents/movie_google_agent.d.ts +24 -0
  24. package/lib/agents/movie_google_agent.js +122 -0
  25. package/lib/cli/bin.js +12 -0
  26. package/lib/index.d.ts +5 -0
  27. package/lib/index.js +5 -0
  28. package/lib/methods/mulmo_script.d.ts +0 -1
  29. package/lib/methods/mulmo_script.js +0 -5
  30. package/lib/methods/mulmo_studio.d.ts +1 -1
  31. package/lib/tools/create_mulmo_script_from_url.js +2 -2
  32. package/lib/tools/create_mulmo_script_interactively.js +2 -2
  33. package/lib/tools/story_to_script.js +2 -2
  34. package/lib/types/index.d.ts +1 -0
  35. package/lib/types/index.js +1 -0
  36. package/lib/types/schema.d.ts +155 -54
  37. package/lib/types/schema.js +14 -2
  38. package/lib/types/type.d.ts +3 -1
  39. package/lib/utils/file.d.ts +1 -0
  40. package/lib/utils/file.js +12 -8
  41. package/lib/utils/image_plugins/image.d.ts +1 -1
  42. package/lib/utils/image_plugins/movie.d.ts +1 -1
  43. package/lib/utils/preprocess.d.ts +9 -3
  44. package/lib/utils/utils.d.ts +1 -0
  45. package/lib/utils/utils.js +3 -0
  46. package/package.json +8 -8
  47. package/scripts/templates/movie_prompts_template.json +50 -0
  48. package/scripts/templates/shorts_template.json +52 -0
@@ -134,7 +134,6 @@ const imageIdSchema = z.string();
134
134
  export const mulmoImageParamsSchema = z
135
135
  .object({
136
136
  model: z.string().optional(), // default: provider specific
137
- size: z.string().optional(), // default: provider specific
138
137
  style: z.string().optional(), // optional image style
139
138
  moderation: z.string().optional(), // optional image style
140
139
  images: z.record(imageIdSchema, mulmoImageMediaSchema).optional(),
@@ -170,6 +169,7 @@ export const mulmoBeatSchema = z
170
169
  .object({
171
170
  speaker: speakerIdSchema.default("Presenter"),
172
171
  text: z.string().describe("Text to be spoken. If empty, the audio is not generated."),
172
+ description: z.string().optional(),
173
173
  image: mulmoImageAssetSchema.optional(),
174
174
  audio: mulmoAudioAssetSchema.optional(),
175
175
  duration: z.number().optional().describe("Duration of the beat. Used only when the text is empty"),
@@ -178,7 +178,8 @@ export const mulmoBeatSchema = z
178
178
  speechOptions: speechOptionsSchema.optional(),
179
179
  textSlideParams: textSlideParamsSchema.optional(),
180
180
  imageNames: z.array(imageIdSchema).optional(), // list of image names to use for image generation. The default is all images in the imageParams.images.
181
- imagePrompt: z.string().optional(), // specified or inserted by preprocessor
181
+ imagePrompt: z.string().optional(),
182
+ moviePrompt: z.string().optional(),
182
183
  })
183
184
  .strict();
184
185
  export const mulmoCanvasDimensionSchema = z
@@ -202,6 +203,13 @@ export const mulmoSpeechParamsSchema = z
202
203
  })
203
204
  .strict();
204
205
  export const text2ImageProviderSchema = z.union([z.literal("openai"), z.literal("google")]).default("openai");
206
+ export const text2MovieProviderSchema = z.union([z.literal("openai"), z.literal("google")]).default("google");
207
+ export const mulmoMovieParamsSchema = z
208
+ .object({
209
+ provider: text2MovieProviderSchema.optional(),
210
+ model: z.string().optional(), // default: provider specific
211
+ })
212
+ .strict();
205
213
  export const mulmoPresentationStyleSchema = z.object({
206
214
  $mulmocast: mulmoCastCreditSchema,
207
215
  canvasSize: mulmoCanvasDimensionSchema, // has default value
@@ -220,6 +228,7 @@ export const mulmoPresentationStyleSchema = z.object({
220
228
  provider: text2ImageProviderSchema, // has default value
221
229
  })
222
230
  .optional(),
231
+ movieParams: mulmoMovieParamsSchema.optional(),
223
232
  // for textSlides
224
233
  textSlideParams: textSlideParamsSchema.optional(),
225
234
  // videoParams: videoParamsSchema.optional(),
@@ -257,6 +266,7 @@ export const mulmoStudioBeatSchema = z
257
266
  duration: z.number().optional(),
258
267
  audioFile: z.string().optional(),
259
268
  imageFile: z.string().optional(), // path to the image
269
+ movieFile: z.string().optional(), // path to the movie file
260
270
  captionFile: z.string().optional(), // path to the caption image
261
271
  })
262
272
  .strict();
@@ -276,6 +286,7 @@ export const mulmoSessionStateSchema = z.object({
276
286
  inBeatSession: z.object({
277
287
  audio: z.set(z.number()),
278
288
  image: z.set(z.number()),
289
+ movie: z.set(z.number()),
279
290
  multiLingual: z.set(z.number()),
280
291
  caption: z.set(z.number()),
281
292
  }),
@@ -298,6 +309,7 @@ export const mulmoStudioSchema = z
298
309
  inBeatSession: {
299
310
  audio: new Set(),
300
311
  image: new Set(),
312
+ movie: new Set(),
301
313
  multiLingual: new Set(),
302
314
  caption: new Set(),
303
315
  },
@@ -1,4 +1,4 @@
1
- import { langSchema, localizedTextSchema, mulmoBeatSchema, mulmoScriptSchema, mulmoStudioSchema, mulmoStudioBeatSchema, mulmoStoryboardSchema, mulmoStoryboardSceneSchema, mulmoStudioMultiLingualSchema, mulmoStudioMultiLingualDataSchema, speakerDictionarySchema, mulmoImageParamsSchema, mulmoSpeechParamsSchema, textSlideParamsSchema, speechOptionsSchema, mulmoCanvasDimensionSchema, mulmoScriptTemplateSchema, text2ImageProviderSchema, text2SpeechProviderSchema, mulmoPresentationStyleSchema, multiLingualTextsSchema, mulmoMermaidMediaSchema, mulmoTextSlideMediaSchema, mulmoMarkdownMediaSchema, mulmoImageMediaSchema, mulmoChartMediaSchema, mediaSourceSchema } from "./schema.js";
1
+ import { langSchema, localizedTextSchema, mulmoBeatSchema, mulmoScriptSchema, mulmoStudioSchema, mulmoStudioBeatSchema, mulmoStoryboardSchema, mulmoStoryboardSceneSchema, mulmoStudioMultiLingualSchema, mulmoStudioMultiLingualDataSchema, speakerDictionarySchema, mulmoImageParamsSchema, mulmoMovieParamsSchema, mulmoSpeechParamsSchema, textSlideParamsSchema, speechOptionsSchema, mulmoCanvasDimensionSchema, mulmoScriptTemplateSchema, text2ImageProviderSchema, text2MovieProviderSchema, text2SpeechProviderSchema, mulmoPresentationStyleSchema, multiLingualTextsSchema, mulmoMermaidMediaSchema, mulmoTextSlideMediaSchema, mulmoMarkdownMediaSchema, mulmoImageMediaSchema, mulmoChartMediaSchema, mediaSourceSchema } from "./schema.js";
2
2
  import { pdf_modes, pdf_sizes, storyToScriptGenerateMode } from "../utils/const.js";
3
3
  import { LLM } from "../utils/utils.js";
4
4
  import { z } from "zod";
@@ -10,6 +10,7 @@ export type SpeechOptions = z.infer<typeof speechOptionsSchema>;
10
10
  export type MulmoImageParams = z.infer<typeof mulmoImageParamsSchema>;
11
11
  export type TextSlideParams = z.infer<typeof textSlideParamsSchema>;
12
12
  export type Text2ImageProvider = z.infer<typeof text2ImageProviderSchema>;
13
+ export type Text2MovieProvider = z.infer<typeof text2MovieProviderSchema>;
13
14
  export type Text2SpeechProvider = z.infer<typeof text2SpeechProviderSchema>;
14
15
  export type LocalizedText = z.infer<typeof localizedTextSchema>;
15
16
  export type MulmoScript = z.infer<typeof mulmoScriptSchema>;
@@ -24,6 +25,7 @@ export type MulmoScriptTemplate = z.infer<typeof mulmoScriptTemplateSchema>;
24
25
  export type MulmoStudioMultiLingual = z.infer<typeof mulmoStudioMultiLingualSchema>;
25
26
  export type MulmoStudioMultiLingualData = z.infer<typeof mulmoStudioMultiLingualDataSchema>;
26
27
  export type MultiLingualTexts = z.infer<typeof multiLingualTextsSchema>;
28
+ export type MulmoMovieParams = z.infer<typeof mulmoMovieParamsSchema>;
27
29
  export type MulmoTextSlideMedia = z.infer<typeof mulmoTextSlideMediaSchema>;
28
30
  export type MulmoMarkdownMedia = z.infer<typeof mulmoMarkdownMediaSchema>;
29
31
  export type MulmoImageMedia = z.infer<typeof mulmoImageMediaSchema>;
@@ -1,6 +1,7 @@
1
1
  import { MulmoScript, MulmoScriptTemplate, MulmoMediaSource, MulmoStudioContext } from "../types/index.js";
2
2
  import { PDFMode } from "../types/index.js";
3
3
  import { ZodSchema } from "zod";
4
+ export declare const updateNpmRoot: (_npmRoot: string) => void;
4
5
  export declare function readMulmoScriptFile<T = MulmoScript>(path: string, errorMessage: string): {
5
6
  mulmoData: T;
6
7
  mulmoDataPath: string;
package/lib/utils/file.js CHANGED
@@ -8,6 +8,10 @@ import { MulmoStudioContextMethods } from "../methods/index.js";
8
8
  import { mulmoScriptTemplateSchema } from "../types/schema.js";
9
9
  const __filename = fileURLToPath(import.meta.url);
10
10
  const __dirname = path.dirname(__filename);
11
+ let npmRoot = path.resolve(__dirname, "../../");
12
+ export const updateNpmRoot = (_npmRoot) => {
13
+ npmRoot = _npmRoot;
14
+ };
11
15
  export function readMulmoScriptFile(arg2, errorMessage) {
12
16
  const scriptPath = path.resolve(arg2);
13
17
  if (!fs.existsSync(scriptPath)) {
@@ -85,7 +89,7 @@ export const getOutputPdfFilePath = (outDirPath, fileName, pdfMode, lang) => {
85
89
  return path.resolve(outDirPath, `${fileName}_${pdfMode}.pdf`);
86
90
  };
87
91
  export const getTemplateFilePath = (templateName) => {
88
- return path.resolve(__dirname, "../../assets/templates/" + templateName + ".json");
92
+ return path.resolve(npmRoot, "./assets/templates/" + templateName + ".json");
89
93
  };
90
94
  export const mkdir = (dirPath) => {
91
95
  if (!fs.existsSync(dirPath)) {
@@ -93,12 +97,12 @@ export const mkdir = (dirPath) => {
93
97
  fs.mkdirSync(dirPath, { recursive: true });
94
98
  }
95
99
  };
96
- export const silentPath = path.resolve(__dirname, "../../assets/audio/silent300.mp3");
97
- export const silentLastPath = path.resolve(__dirname, "../../assets/audio/silent800.mp3");
98
- export const silent60secPath = path.resolve(__dirname, "../../assets/audio/silent60sec.mp3");
99
- export const defaultBGMPath = path.resolve(__dirname, "../../assets/music/StarsBeyondEx.mp3");
100
+ export const silentPath = path.resolve(npmRoot, "./assets/audio/silent300.mp3");
101
+ export const silentLastPath = path.resolve(npmRoot, "./assets/audio/silent800.mp3");
102
+ export const silent60secPath = path.resolve(npmRoot, "./assets/audio/silent60sec.mp3");
103
+ export const defaultBGMPath = path.resolve(npmRoot, "./assets/music/StarsBeyondEx.mp3");
100
104
  export const getHTMLFile = (filename) => {
101
- const htmlPath = path.resolve(__dirname, `../../assets/html/${filename}.html`);
105
+ const htmlPath = path.resolve(npmRoot, `./assets/html/${filename}.html`);
102
106
  return fs.readFileSync(htmlPath, "utf-8");
103
107
  };
104
108
  // for cli
@@ -121,7 +125,7 @@ export const getFullPath = (baseDirPath, file) => {
121
125
  return path.resolve(file);
122
126
  };
123
127
  export const readScriptTemplateFile = (scriptName) => {
124
- const scriptPath = path.resolve(__dirname, "../../scripts/templates", scriptName);
128
+ const scriptPath = path.resolve(npmRoot, "./scripts/templates", scriptName);
125
129
  const scriptData = fs.readFileSync(scriptPath, "utf-8");
126
130
  // NOTE: We don't want to schema parse the script here to eliminate default values.
127
131
  return JSON.parse(scriptData);
@@ -142,7 +146,7 @@ export const readTemplatePrompt = (templateName) => {
142
146
  return prompt;
143
147
  };
144
148
  export const getAvailableTemplates = () => {
145
- const templatesDir = path.resolve(__dirname, "../../assets/templates");
149
+ const templatesDir = path.resolve(npmRoot, "./assets/templates");
146
150
  if (!fs.existsSync(templatesDir)) {
147
151
  return [];
148
152
  }
@@ -1,2 +1,2 @@
1
1
  export declare const imageType = "image";
2
- export declare const process: (params: import("../../types/type.js").ImageProcessorParams) => string | undefined;
2
+ export declare const process: (params: import("../../index.js").ImageProcessorParams) => string | undefined;
@@ -1,2 +1,2 @@
1
1
  export declare const imageType = "movie";
2
- export declare const process: (params: import("../../types/type.js").ImageProcessorParams) => string | undefined;
2
+ export declare const process: (params: import("../../index.js").ImageProcessorParams) => string | undefined;
@@ -5,6 +5,7 @@ export declare const createOrUpdateStudioData: (_mulmoScript: MulmoScript, curre
5
5
  hash?: string | undefined;
6
6
  audioFile?: string | undefined;
7
7
  imageFile?: string | undefined;
8
+ movieFile?: string | undefined;
8
9
  captionFile?: string | undefined;
9
10
  }[];
10
11
  multiLingual: {
@@ -168,9 +169,9 @@ export declare const createOrUpdateStudioData: (_mulmoScript: MulmoScript, curre
168
169
  type: "midi";
169
170
  source: string;
170
171
  } | undefined;
172
+ description?: string | undefined;
171
173
  imageParams?: {
172
174
  model?: string | undefined;
173
- size?: string | undefined;
174
175
  style?: string | undefined;
175
176
  moderation?: string | undefined;
176
177
  images?: Record<string, {
@@ -198,13 +199,14 @@ export declare const createOrUpdateStudioData: (_mulmoScript: MulmoScript, curre
198
199
  } | undefined;
199
200
  imageNames?: string[] | undefined;
200
201
  imagePrompt?: string | undefined;
202
+ moviePrompt?: string | undefined;
201
203
  }[];
202
204
  lang?: string | undefined;
203
205
  title?: string | undefined;
206
+ description?: string | undefined;
204
207
  imageParams?: {
205
208
  provider: "openai" | "google";
206
209
  model?: string | undefined;
207
- size?: string | undefined;
208
210
  style?: string | undefined;
209
211
  moderation?: string | undefined;
210
212
  images?: Record<string, {
@@ -227,8 +229,11 @@ export declare const createOrUpdateStudioData: (_mulmoScript: MulmoScript, curre
227
229
  textSlideParams?: {
228
230
  cssStyles: string | string[];
229
231
  } | undefined;
232
+ movieParams?: {
233
+ model?: string | undefined;
234
+ provider?: "openai" | "google" | undefined;
235
+ } | undefined;
230
236
  omitCaptions?: boolean | undefined;
231
- description?: string | undefined;
232
237
  references?: {
233
238
  type: "image" | "audio" | "article" | "paper" | "video";
234
239
  url: string;
@@ -250,6 +255,7 @@ export declare const createOrUpdateStudioData: (_mulmoScript: MulmoScript, curre
250
255
  };
251
256
  inBeatSession: {
252
257
  image: Set<number>;
258
+ movie: Set<number>;
253
259
  audio: Set<number>;
254
260
  multiLingual: Set<number>;
255
261
  caption: Set<number>;
@@ -15,3 +15,4 @@ export declare const chunkArray: <T>(array: T[], size?: number) => T[][];
15
15
  export declare const isHttp: (fileOrUrl: string) => boolean;
16
16
  export declare const text2hash: (input: string) => string;
17
17
  export declare const localizedText: (beat: MulmoBeat, multiLingualData?: MulmoStudioMultiLingualData, lang?: string) => string;
18
+ export declare const sleep: (milliseconds: number) => Promise<unknown>;
@@ -52,3 +52,6 @@ export const localizedText = (beat, multiLingualData, lang) => {
52
52
  }
53
53
  return beat.text;
54
54
  };
55
+ export const sleep = async (milliseconds) => {
56
+ return await new Promise((resolve) => setTimeout(resolve, milliseconds));
57
+ };
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "mulmocast",
3
- "version": "0.0.9",
3
+ "version": "0.0.11",
4
4
  "description": "",
5
5
  "type": "module",
6
- "main": "lib/cli/bin.js",
6
+ "main": "lib/index.js",
7
7
  "bin": {
8
8
  "mulmo": "lib/cli/bin.js"
9
9
  },
@@ -69,27 +69,27 @@
69
69
  "google-auth-library": "^9.15.1",
70
70
  "graphai": "^2.0.5",
71
71
  "inquirer": "^12.6.1",
72
- "marked": "^15.0.11",
72
+ "marked": "^15.0.12",
73
73
  "ora": "^8.2.0",
74
74
  "pdf-lib": "^1.17.1",
75
- "puppeteer": "^24.8.1",
75
+ "puppeteer": "^24.10.0",
76
76
  "yaml": "^2.8.0",
77
77
  "yargs": "^17.7.2",
78
- "zod": "^3.24.4",
78
+ "zod": "^3.25.51",
79
79
  "zod-to-json-schema": "^3.24.5"
80
80
  },
81
81
  "devDependencies": {
82
82
  "@receptron/test_utils": "^2.0.0",
83
83
  "@types/fluent-ffmpeg": "^2.1.26",
84
84
  "@types/yargs": "^17.0.33",
85
- "eslint": "^9.27.0",
85
+ "eslint": "^9.28.0",
86
86
  "eslint-config-prettier": "^10.1.5",
87
- "eslint-plugin-prettier": "^5.4.0",
87
+ "eslint-plugin-prettier": "^5.4.1",
88
88
  "prettier": "^3.3.3",
89
89
  "ts-node": "^10.9.2",
90
90
  "tsx": "^4.19.4",
91
91
  "typescript": "^5.7.3",
92
- "typescript-eslint": "^8.32.1"
92
+ "typescript-eslint": "^8.33.1"
93
93
  },
94
94
  "engines": {
95
95
  "node": ">=16.0.0"
@@ -0,0 +1,50 @@
1
+ {
2
+ "$mulmocast": {
3
+ "version": "1.0",
4
+ "credit": "closing"
5
+ },
6
+ "title": "[TITLE: Brief, engaging title for the topic]",
7
+ "lang": "en",
8
+ "references": [
9
+ {
10
+ "url": "[SOURCE_URL: URL of the source material]",
11
+ "title": "[SOURCE_TITLE: Title of the referenced article, or paper]",
12
+ "type": "[SOURCE_TYPE: article, paper]"
13
+ }
14
+ ],
15
+ "movieParams": {
16
+ "provider": "google"
17
+ },
18
+ "beats": [
19
+ {
20
+ "text": "[OPENING_BEAT: Introduce the topic with a hook. Reference the source material and set up why this topic matters. Usually 2-3 sentences that grab attention and provide context.]",
21
+ "imagePrompt": "[IMAGE_PROMPT: A prompt for the image to be generated for this beat.]",
22
+ "moviePrompt": "[MOVIE_PROMPT: A movie prompt for that image.]"
23
+ },
24
+ {
25
+ "text": "[MAIN_CONCEPT: Define or explain the core concept/idea. This should be the central focus of your narrative. Keep it clear and accessible.]",
26
+ "imagePrompt": "[IMAGE_PROMPT: A prompt for the image to be generated for this beat.]",
27
+ "moviePrompt": "[MOVIE_PROMPT: A movie prompt for that image.]"
28
+ },
29
+ {
30
+ "text": "[SUPPORTING_DETAIL_1: Additional context, examples, or elaboration that helps illustrate the main concept. This could include how it works, why it's important, or real-world applications.]",
31
+ "imagePrompt": "[IMAGE_PROMPT: A prompt for the image to be generated for this beat.]",
32
+ "moviePrompt": "[MOVIE_PROMPT: A movie prompt for that image.]"
33
+ },
34
+ {
35
+ "text": "[SUPPORTING_DETAIL_2: Continue with more examples, deeper explanation, or different aspects of the topic if needed.]",
36
+ "imagePrompt": "[IMAGE_PROMPT: A prompt for the image to be generated for this beat.]",
37
+ "moviePrompt": "[MOVIE_PROMPT: A movie prompt for that image.]"
38
+ },
39
+ {
40
+ "text": "[ADDITIONAL_BEATS: Add more beats as necessary to fully explore the topic. Complex topics may require 6-10+ beats to cover adequately. Each beat should advance the narrative or provide valuable information.]",
41
+ "imagePrompt": "[IMAGE_PROMPT: A prompt for the image to be generated for this beat.]",
42
+ "moviePrompt": "[MOVIE_PROMPT: A movie prompt for that image.]"
43
+ },
44
+ {
45
+ "text": "[CONCLUSION/IMPACT: Wrap up with the significance, implications, or key takeaway. Help the audience understand why this matters to them.]",
46
+ "imagePrompt": "[IMAGE_PROMPT: A prompt for the image to be generated for this beat.]",
47
+ "moviePrompt": "[MOVIE_PROMPT: A movie prompt for that image.]"
48
+ }
49
+ ]
50
+ }
@@ -0,0 +1,52 @@
1
+ {
2
+ "$mulmocast": {
3
+ "version": "1.0"
4
+ },
5
+ "title": "[TITLE: Brief, engaging title for the topic]",
6
+ "lang": "en",
7
+ "movieParams": {
8
+ "provider": "google"
9
+ },
10
+ "beats": [
11
+ {
12
+ "text": "[NARRATION: Short narration for the beat. Up to 20 words]",
13
+ "imagePrompt": "[IMAGE_PROMPT: A prompt for the image to be generated for this beat.]",
14
+ "moviePrompt": "[MOVIE_PROMPT: A movie prompt for that image.]"
15
+ },
16
+ {
17
+ "text": "[NARRATION: Short narration for the beat. Up to 20 words]",
18
+ "imagePrompt": "[IMAGE_PROMPT: A prompt for the image to be generated for this beat.]",
19
+ "moviePrompt": "[MOVIE_PROMPT: A movie prompt for that image.]"
20
+ },
21
+ {
22
+ "text": "[NARRATION: Short narration for the beat. Up to 20 words]",
23
+ "imagePrompt": "[IMAGE_PROMPT: A prompt for the image to be generated for this beat.]",
24
+ "moviePrompt": "[MOVIE_PROMPT: A movie prompt for that image.]"
25
+ },
26
+ {
27
+ "text": "[NARRATION: Short narration for the beat. Up to 20 words]",
28
+ "imagePrompt": "[IMAGE_PROMPT: A prompt for the image to be generated for this beat.]",
29
+ "moviePrompt": "[MOVIE_PROMPT: A movie prompt for that image.]"
30
+ },
31
+ {
32
+ "text": "[NARRATION: Short narration for the beat. Up to 20 words]",
33
+ "imagePrompt": "[IMAGE_PROMPT: A prompt for the image to be generated for this beat.]",
34
+ "moviePrompt": "[MOVIE_PROMPT: A movie prompt for that image.]"
35
+ },
36
+ {
37
+ "text": "[NARRATION: Short narration for the beat. Up to 20 words]",
38
+ "imagePrompt": "[IMAGE_PROMPT: A prompt for the image to be generated for this beat.]",
39
+ "moviePrompt": "[MOVIE_PROMPT: A movie prompt for that image.]"
40
+ },
41
+ {
42
+ "text": "[NARRATION: Short narration for the beat. Up to 20 words]",
43
+ "imagePrompt": "[IMAGE_PROMPT: A prompt for the image to be generated for this beat.]",
44
+ "moviePrompt": "[MOVIE_PROMPT: A movie prompt for that image.]"
45
+ },
46
+ {
47
+ "text": "[NARRATION: Short narration for the beat. Up to 20 words]",
48
+ "imagePrompt": "[IMAGE_PROMPT: A prompt for the image to be generated for this beat.]",
49
+ "moviePrompt": "[MOVIE_PROMPT: A movie prompt for that image.]"
50
+ }
51
+ ]
52
+ }