mulmocast 0.1.6 → 1.1.0

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 (58) hide show
  1. package/assets/templates/akira_comic.json +1 -1
  2. package/assets/templates/ani.json +48 -0
  3. package/assets/templates/ani_ja.json +44 -0
  4. package/assets/templates/characters.json +1 -1
  5. package/assets/templates/children_book.json +1 -1
  6. package/assets/templates/comic_strips.json +1 -1
  7. package/assets/templates/drslump_comic.json +1 -1
  8. package/assets/templates/ghibli_comic.json +1 -1
  9. package/assets/templates/ghibli_image_only.json +1 -1
  10. package/assets/templates/ghibli_shorts.json +2 -3
  11. package/assets/templates/ghost_comic.json +1 -1
  12. package/assets/templates/onepiece_comic.json +1 -1
  13. package/assets/templates/portrait_movie.json +1 -1
  14. package/assets/templates/realistic_movie.json +1 -1
  15. package/assets/templates/sensei_and_taro.json +4 -5
  16. package/assets/templates/shorts.json +1 -1
  17. package/assets/templates/trailer.json +1 -1
  18. package/lib/actions/audio.js +8 -7
  19. package/lib/actions/image_agents.d.ts +53 -98
  20. package/lib/actions/image_agents.js +14 -6
  21. package/lib/actions/images.js +42 -13
  22. package/lib/actions/movie.js +1 -1
  23. package/lib/agents/index.d.ts +2 -1
  24. package/lib/agents/index.js +2 -1
  25. package/lib/agents/movie_replicate_agent.js +18 -5
  26. package/lib/agents/sound_effect_replicate_agent.d.ts +5 -0
  27. package/lib/agents/sound_effect_replicate_agent.js +59 -0
  28. package/lib/cli/commands/tool/scripting/builder.js +1 -1
  29. package/lib/cli/commands/tool/scripting/handler.d.ts +1 -1
  30. package/lib/cli/commands/tool/story_to_script/builder.js +1 -1
  31. package/lib/cli/commands/tool/story_to_script/handler.d.ts +1 -1
  32. package/lib/mcp/server.js +2 -2
  33. package/lib/methods/index.d.ts +1 -0
  34. package/lib/methods/index.js +1 -0
  35. package/lib/methods/mulmo_presentation_style.d.ts +25 -6
  36. package/lib/methods/mulmo_presentation_style.js +33 -30
  37. package/lib/methods/mulmo_script.d.ts +4 -0
  38. package/lib/methods/mulmo_script.js +31 -0
  39. package/lib/tools/story_to_script.d.ts +1 -1
  40. package/lib/types/agent.d.ts +9 -0
  41. package/lib/types/schema.d.ts +727 -554
  42. package/lib/types/schema.js +41 -24
  43. package/lib/types/type.d.ts +4 -4
  44. package/lib/utils/assets.d.ts +18 -0
  45. package/lib/utils/assets.js +101 -0
  46. package/lib/utils/context.d.ts +98 -84
  47. package/lib/utils/context.js +2 -1
  48. package/lib/utils/ffmpeg_utils.js +6 -0
  49. package/lib/utils/file.d.ts +4 -1
  50. package/lib/utils/file.js +3 -5
  51. package/lib/utils/preprocess.d.ts +57 -47
  52. package/lib/utils/preprocess.js +7 -5
  53. package/lib/utils/provider2agent.d.ts +27 -7
  54. package/lib/utils/provider2agent.js +85 -7
  55. package/lib/utils/utils.d.ts +1 -2
  56. package/lib/utils/utils.js +4 -2
  57. package/package.json +7 -7
  58. package/scripts/templates/presentation.json~ +0 -119
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod";
2
- import { htmlLLMProvider, provider2TTSAgent, provider2ImageAgent, provider2MovieAgent, defaultProviders } from "../utils/provider2agent.js";
2
+ import { htmlLLMProvider, provider2TTSAgent, provider2ImageAgent, provider2MovieAgent, defaultProviders, provider2SoundEffectAgent, } from "../utils/provider2agent.js";
3
3
  export const langSchema = z.string();
4
4
  const URLStringSchema = z.string().url();
5
5
  export const localizedTextSchema = z
@@ -26,6 +26,7 @@ export const speakerDataSchema = z
26
26
  .object({
27
27
  displayName: z.record(langSchema, z.string()).optional(),
28
28
  voiceId: z.string(),
29
+ isDefault: z.boolean().optional(),
29
30
  speechOptions: speechOptionsSchema.optional(),
30
31
  provider: text2SpeechProviderSchema.optional(),
31
32
  model: z.string().optional().describe("TTS model to use for this speaker"),
@@ -96,7 +97,7 @@ export const mulmoChartMediaSchema = z
96
97
  .object({
97
98
  type: z.literal("chart"),
98
99
  title: z.string(),
99
- chartData: z.record(z.any()),
100
+ chartData: z.record(z.string(), z.any()),
100
101
  })
101
102
  .strict();
102
103
  export const mulmoMermaidMediaSchema = z
@@ -223,12 +224,18 @@ export const htmlPromptParamsSchema = z
223
224
  systemPrompt: z.string().default("").optional(),
224
225
  prompt: z.string().default(""),
225
226
  data: z.any().optional(),
226
- images: z.record(z.any()).optional(),
227
+ images: z.record(z.string(), z.any()).optional(),
227
228
  })
228
229
  .strict();
230
+ export const text2MovieProviderSchema = z.enum(Object.keys(provider2MovieAgent)).default(defaultProviders.text2movie);
231
+ export const text2SoundEffectProviderSchema = z.enum(Object.keys(provider2SoundEffectAgent)).default(defaultProviders.soundEffect);
232
+ export const mulmoSoundEffectParamsSchema = z.object({
233
+ provider: text2SoundEffectProviderSchema.optional(),
234
+ model: z.string().optional(), // default: provider specific
235
+ });
229
236
  export const mulmoBeatSchema = z
230
237
  .object({
231
- speaker: speakerIdSchema.default("Presenter"),
238
+ speaker: speakerIdSchema.optional(),
232
239
  text: z.string().default("").describe("Text to be spoken. If empty, the audio is not generated."),
233
240
  id: z.string().optional().describe("Unique identifier for the beat."),
234
241
  description: z.string().optional(),
@@ -239,11 +246,13 @@ export const mulmoBeatSchema = z
239
246
  audioParams: beatAudioParamsSchema.optional(), // beat specific parameters
240
247
  movieParams: z
241
248
  .object({
249
+ provider: text2MovieProviderSchema.optional(),
242
250
  model: z.string().optional(),
243
- fillOption: mulmoFillOptionSchema.optional(),
244
- speed: z.number().optional().describe("Speed of the video. 1.0 is normal speed. 0.5 is half speed. 2.0 is double speed."),
251
+ fillOption: mulmoFillOptionSchema.optional(), // for movie.ts
252
+ speed: z.number().optional().describe("Speed of the video. 1.0 is normal speed. 0.5 is half speed. 2.0 is double speed."), // for movie.ts
245
253
  })
246
254
  .optional(),
255
+ soundEffectParams: mulmoSoundEffectParamsSchema.optional(),
247
256
  htmlImageParams: mulmoHtmlImageParamsSchema.optional(),
248
257
  speechOptions: speechOptionsSchema.optional(),
249
258
  textSlideParams: textSlideParamsSchema.optional(),
@@ -251,6 +260,7 @@ export const mulmoBeatSchema = z
251
260
  imageNames: z.array(imageIdSchema).optional(), // list of image names to use for image generation. The default is all images in the imageParams.images.
252
261
  imagePrompt: z.string().optional(),
253
262
  moviePrompt: z.string().optional(),
263
+ soundEffectPrompt: z.string().optional(),
254
264
  htmlPrompt: htmlPromptParamsSchema.optional(),
255
265
  })
256
266
  .strict();
@@ -263,19 +273,11 @@ export const mulmoCanvasDimensionSchema = z
263
273
  // export const voiceMapSchema = z.record(speakerIdSchema, z.string())
264
274
  export const mulmoCastCreditSchema = z
265
275
  .object({
266
- version: z.literal("1.0"),
276
+ version: z.literal("1.1"),
267
277
  credit: z.literal("closing").optional(),
268
278
  })
269
279
  .strict();
270
- export const mulmoSpeechParamsSchema = z
271
- .object({
272
- provider: text2SpeechProviderSchema, // has default value
273
- speakers: speakerDictionarySchema,
274
- model: z.string().optional().describe("Default TTS model to use"),
275
- })
276
- .strict();
277
280
  export const text2HtmlImageProviderSchema = z.enum(htmlLLMProvider).default(defaultProviders.text2Html);
278
- export const text2MovieProviderSchema = z.enum(Object.keys(provider2MovieAgent)).default(defaultProviders.text2movie);
279
281
  // NOTE: This is UI only. (until we figure out how to use it in mulmoMovieParamsSchema)
280
282
  export const mulmoGoogleMovieModelSchema = z
281
283
  .object({
@@ -296,27 +298,40 @@ export const mulmoTransitionSchema = z.object({
296
298
  });
297
299
  export const mulmoMovieParamsSchema = z
298
300
  .object({
299
- provider: text2MovieProviderSchema.optional(),
300
- model: z.string().optional(), // default: provider specific
301
- transition: mulmoTransitionSchema.optional(),
302
- fillOption: mulmoFillOptionSchema.optional(),
301
+ provider: text2MovieProviderSchema.optional(), // for agent
302
+ model: z.string().optional(), // default: provider specific. for agent
303
+ transition: mulmoTransitionSchema.optional(), // for movie.ts
304
+ fillOption: mulmoFillOptionSchema.optional(), // for movie.ts
303
305
  })
304
306
  .strict();
307
+ const defaultSpeaker = "Presenter";
305
308
  export const mulmoPresentationStyleSchema = z.object({
306
309
  $mulmocast: mulmoCastCreditSchema,
307
310
  canvasSize: mulmoCanvasDimensionSchema, // has default value
308
- speechParams: mulmoSpeechParamsSchema.default({
311
+ speechParams: z
312
+ .object({
313
+ speakers: speakerDictionarySchema,
314
+ })
315
+ .default({
309
316
  speakers: {
310
- Presenter: {
317
+ [defaultSpeaker]: {
311
318
  voiceId: "shimmer",
312
319
  displayName: {
313
- en: "Presenter",
320
+ en: defaultSpeaker,
314
321
  },
315
322
  },
316
323
  },
317
324
  }),
318
- imageParams: mulmoImageParamsSchema.optional(),
319
- movieParams: mulmoMovieParamsSchema.optional(),
325
+ imageParams: mulmoImageParamsSchema.optional().default({
326
+ provider: defaultProviders.text2image,
327
+ images: {},
328
+ }),
329
+ movieParams: mulmoMovieParamsSchema.optional().default({
330
+ provider: defaultProviders.text2movie,
331
+ }),
332
+ soundEffectParams: mulmoSoundEffectParamsSchema.optional().default({
333
+ provider: defaultProviders.soundEffect,
334
+ }),
320
335
  htmlImageParams: mulmoHtmlImageParamsSchema
321
336
  .extend({
322
337
  provider: text2HtmlImageProviderSchema,
@@ -365,6 +380,7 @@ export const mulmoStudioBeatSchema = z
365
380
  audioFile: z.string().optional(),
366
381
  imageFile: z.string().optional(), // path to the image
367
382
  movieFile: z.string().optional(), // path to the movie file
383
+ soundEffectFile: z.string().optional(), // path to the sound effect file
368
384
  captionFile: z.string().optional(), // path to the caption image
369
385
  })
370
386
  .strict();
@@ -389,6 +405,7 @@ export const mulmoSessionStateSchema = z.object({
389
405
  caption: z.record(z.number().int(), z.boolean()),
390
406
  html: z.record(z.number().int(), z.boolean()),
391
407
  imageReference: z.record(z.number().int(), z.boolean()),
408
+ soundEffect: z.record(z.number().int(), z.boolean()),
392
409
  }),
393
410
  });
394
411
  export const mulmoStudioSchema = z
@@ -1,11 +1,10 @@
1
- import { langSchema, localizedTextSchema, mulmoBeatSchema, mulmoScriptSchema, mulmoStudioSchema, mulmoStudioBeatSchema, mulmoStoryboardSchema, mulmoStoryboardSceneSchema, mulmoStudioMultiLingualSchema, mulmoStudioMultiLingualDataSchema, speakerDictionarySchema, mulmoImageParamsSchema, mulmoImageParamsImagesSchema, mulmoFillOptionSchema, mulmoMovieParamsSchema, mulmoSpeechParamsSchema, textSlideParamsSchema, speechOptionsSchema, speakerDataSchema, mulmoCanvasDimensionSchema, mulmoScriptTemplateSchema, mulmoScriptTemplateFileSchema, text2ImageProviderSchema, text2HtmlImageProviderSchema, text2MovieProviderSchema, text2SpeechProviderSchema, mulmoPresentationStyleSchema, multiLingualTextsSchema, mulmoMermaidMediaSchema, mulmoTextSlideMediaSchema, mulmoMarkdownMediaSchema, mulmoImageMediaSchema, mulmoChartMediaSchema, mediaSourceSchema, mulmoSessionStateSchema, mulmoOpenAIImageModelSchema, mulmoGoogleImageModelSchema, mulmoGoogleMovieModelSchema, mulmoReplicateMovieModelSchema, mulmoImagePromptMediaSchema } from "./schema.js";
1
+ import { langSchema, localizedTextSchema, mulmoBeatSchema, mulmoScriptSchema, mulmoStudioSchema, mulmoStudioBeatSchema, mulmoStoryboardSchema, mulmoStoryboardSceneSchema, mulmoStudioMultiLingualSchema, mulmoStudioMultiLingualDataSchema, speakerDictionarySchema, mulmoImageParamsSchema, mulmoImageParamsImagesSchema, mulmoFillOptionSchema, mulmoMovieParamsSchema, textSlideParamsSchema, speechOptionsSchema, speakerDataSchema, mulmoCanvasDimensionSchema, mulmoScriptTemplateSchema, mulmoScriptTemplateFileSchema, text2ImageProviderSchema, text2HtmlImageProviderSchema, text2MovieProviderSchema, text2SpeechProviderSchema, mulmoPresentationStyleSchema, multiLingualTextsSchema, mulmoImageAssetSchema, mulmoMermaidMediaSchema, mulmoTextSlideMediaSchema, mulmoMarkdownMediaSchema, mulmoImageMediaSchema, mulmoChartMediaSchema, mediaSourceSchema, mulmoSessionStateSchema, mulmoOpenAIImageModelSchema, mulmoGoogleImageModelSchema, mulmoGoogleMovieModelSchema, mulmoReplicateMovieModelSchema, mulmoImagePromptMediaSchema } from "./schema.js";
2
2
  import { pdf_modes, pdf_sizes, storyToScriptGenerateMode } from "../utils/const.js";
3
- import { LLM } from "../utils/utils.js";
3
+ import type { LLM } from "../utils/provider2agent.js";
4
4
  import { z } from "zod";
5
5
  export type LANG = z.infer<typeof langSchema>;
6
6
  export type MulmoBeat = z.infer<typeof mulmoBeatSchema>;
7
7
  export type SpeakerDictonary = z.infer<typeof speakerDictionarySchema>;
8
- export type MulmoSpeechParams = z.infer<typeof mulmoSpeechParamsSchema>;
9
8
  export type SpeechOptions = z.infer<typeof speechOptionsSchema>;
10
9
  export type SpeakerData = z.infer<typeof speakerDataSchema>;
11
10
  export type MulmoImageParams = z.infer<typeof mulmoImageParamsSchema>;
@@ -36,6 +35,7 @@ export type MulmoGoogleImageModel = z.infer<typeof mulmoGoogleImageModelSchema>;
36
35
  export type MulmoGoogleMovieModel = z.infer<typeof mulmoGoogleMovieModelSchema>;
37
36
  export type MulmoReplicateMovieModel = z.infer<typeof mulmoReplicateMovieModelSchema>;
38
37
  export type MulmoImagePromptMedia = z.infer<typeof mulmoImagePromptMediaSchema>;
38
+ export type MulmoImageAsset = z.infer<typeof mulmoImageAssetSchema>;
39
39
  export type MulmoTextSlideMedia = z.infer<typeof mulmoTextSlideMediaSchema>;
40
40
  export type MulmoMarkdownMedia = z.infer<typeof mulmoMarkdownMediaSchema>;
41
41
  export type MulmoImageMedia = z.infer<typeof mulmoImageMediaSchema>;
@@ -91,7 +91,7 @@ export type Text2HtmlAgentInfo = {
91
91
  export type BeatMediaType = "movie" | "image";
92
92
  export type StoryToScriptGenerateMode = (typeof storyToScriptGenerateMode)[keyof typeof storyToScriptGenerateMode];
93
93
  export type SessionType = "audio" | "image" | "video" | "multiLingual" | "caption" | "pdf";
94
- export type BeatSessionType = "audio" | "image" | "multiLingual" | "caption" | "movie" | "html" | "imageReference";
94
+ export type BeatSessionType = "audio" | "image" | "multiLingual" | "caption" | "movie" | "html" | "imageReference" | "soundEffect";
95
95
  export type SessionProgressEvent = {
96
96
  kind: "session";
97
97
  sessionType: SessionType;
@@ -0,0 +1,18 @@
1
+ type BgmAsset = {
2
+ name: string;
3
+ title: string;
4
+ url: string;
5
+ suno_url: string;
6
+ date: string;
7
+ duration: string;
8
+ account: string;
9
+ original_license: string;
10
+ prompt: string;
11
+ model: string;
12
+ };
13
+ export type BgmAssets = {
14
+ license: string;
15
+ bgms: BgmAsset[];
16
+ };
17
+ export declare const bgmAssets: BgmAssets;
18
+ export {};
@@ -0,0 +1,101 @@
1
+ export const bgmAssets = {
2
+ license: "Free to distribute as the BMG of media generated by MulmoCast, including commercial use.",
3
+ bgms: [
4
+ {
5
+ name: "story001.mp3",
6
+ title: "Whispered Melody",
7
+ url: "https://github.com/receptron/mulmocast-media/raw/refs/heads/main/bgms/story001.mp3",
8
+ suno_url: "https://suno.com/s/v6zer50aQJu8Y0qA",
9
+ date: "2025-06-17",
10
+ duration: "03:17",
11
+ account: "@snakajima",
12
+ original_license: "Generated by Suno with commercial use rights (PRO Plan)",
13
+ prompt: "instrumental, smooth, piano",
14
+ model: "v4.5 beta",
15
+ },
16
+ {
17
+ name: "story002.mp3",
18
+ title: "Rise and Shine",
19
+ url: "https://github.com/receptron/mulmocast-media/raw/refs/heads/main/bgms/story002.mp3",
20
+ suno_url: "https://suno.com/s/mJnvyu3UXnkdAPfQ",
21
+ date: "2025-06-17",
22
+ duration: "04:04",
23
+ account: "@snakajima",
24
+ original_license: "Generated by Suno with commercial use rights (PRO Plan)",
25
+ prompt: "techno, inspiring, piano",
26
+ model: "v4.5 beta",
27
+ },
28
+ {
29
+ name: "story003.mp3",
30
+ title: "Chasing the Sunset",
31
+ url: "https://github.com/receptron/mulmocast-media/raw/refs/heads/main/bgms/story003.mp3",
32
+ suno_url: "https://suno.com/s/2zGjMQ9vURJbaMZA",
33
+ date: "2025-06-17",
34
+ duration: "02:49",
35
+ account: "@snakajima",
36
+ original_license: "Generated by Suno with commercial use rights (PRO Plan)",
37
+ prompt: "piano, inspiring, sunset",
38
+ model: "v4.5 beta",
39
+ },
40
+ {
41
+ name: "story004.mp3",
42
+ title: "Whispering Keys",
43
+ url: "https://github.com/receptron/mulmocast-media/raw/refs/heads/main/bgms/story004.mp3",
44
+ suno_url: "https://suno.com/s/0SFoBRsBWsncw6tu",
45
+ date: "2025-06-17",
46
+ duration: "04:00",
47
+ account: "@snakajima",
48
+ original_license: "Generated by Suno with commercial use rights (PRO Plan)",
49
+ prompt: "Piano, classical, ambient",
50
+ model: "v4",
51
+ },
52
+ {
53
+ name: "story005.mp3",
54
+ title: "Whisper of Ivory",
55
+ url: "https://github.com/receptron/mulmocast-media/raw/refs/heads/main/bgms/story005.mp3",
56
+ suno_url: "https://suno.com/s/0SFoBRsBWsncw6tu",
57
+ date: "2025-06-17",
58
+ duration: "04:00",
59
+ account: "@snakajima",
60
+ original_license: "Generated by Suno with commercial use rights (PRO Plan)",
61
+ prompt: "Piano solo, classical, ambient",
62
+ model: "v4",
63
+ },
64
+ {
65
+ name: "theme001.mp3",
66
+ title: "Rise of the Flame",
67
+ url: "https://github.com/receptron/mulmocast-media/raw/refs/heads/main/bgms/theme001.mp3",
68
+ suno_url: "https://suno.com/s/WhYOf8oJYhBgSKET",
69
+ date: "2025-06-20",
70
+ duration: "03:23",
71
+ account: "@snakajima",
72
+ original_license: "Generated by Suno with commercial use rights (PRO Plan)",
73
+ prompt: "Olympic Theme, classical, emotional",
74
+ model: "v4",
75
+ },
76
+ {
77
+ name: "olympic001.mp3",
78
+ title: "Olympic-style Theme Music",
79
+ url: "https://github.com/receptron/mulmocast-media/raw/refs/heads/main/bgms/olympic001.mp3",
80
+ suno_url: "https://suno.com/s/32wpnmCrkFVvkTSQ",
81
+ date: "2025-07-17",
82
+ duration: "02:54",
83
+ account: "@snakajima",
84
+ original_license: "Generated by Suno with commercial use rights (PRO Plan)",
85
+ prompt: "Epic orchestral fanfare in the style of John Williams' Olympic Fanfare and Theme. Bright brass fanfare, soaring strings, powerful percussion, and heroic French horn melodies. Triumphant and majestic mood, suitable for an opening ceremony or national celebration. Emphasize dynamic builds, rich harmonies, and cinematic grandeur.",
86
+ model: "v4.5+",
87
+ },
88
+ {
89
+ name: "morning001.mp3",
90
+ title: "Morning Dance",
91
+ url: "https://github.com/receptron/mulmocast-media/raw/refs/heads/main/bgms/morning001.mp3",
92
+ suno_url: "https://suno.com/s/9MTkutZYqxeyBlwK",
93
+ date: "2025-07-17",
94
+ duration: "03:52",
95
+ account: "@snakajima",
96
+ original_license: "morning, piano solo, Japanese name, sexy",
97
+ prompt: "morning, piano solo, Japanese name, sexy",
98
+ model: "v4.5+",
99
+ },
100
+ ],
101
+ };
@@ -16,9 +16,35 @@ export declare const initializeContextFromFiles: (files: FileObject, raiseError:
16
16
  audioFile?: string | undefined;
17
17
  imageFile?: string | undefined;
18
18
  movieFile?: string | undefined;
19
+ soundEffectFile?: string | undefined;
19
20
  captionFile?: string | undefined;
20
21
  }[];
21
22
  script: {
23
+ imageParams: {
24
+ provider: string;
25
+ model?: string | undefined;
26
+ style?: string | undefined;
27
+ moderation?: string | undefined;
28
+ images?: Record<string, {
29
+ type: "image";
30
+ source: {
31
+ url: string;
32
+ kind: "url";
33
+ } | {
34
+ kind: "base64";
35
+ data: string;
36
+ } | {
37
+ text: string;
38
+ kind: "text";
39
+ } | {
40
+ path: string;
41
+ kind: "path";
42
+ };
43
+ } | {
44
+ type: "imagePrompt";
45
+ prompt: string;
46
+ }> | undefined;
47
+ };
22
48
  audioParams: {
23
49
  padding: number;
24
50
  introPadding: number;
@@ -41,8 +67,23 @@ export declare const initializeContextFromFiles: (files: FileObject, raiseError:
41
67
  kind: "path";
42
68
  } | undefined;
43
69
  };
70
+ movieParams: {
71
+ provider?: string | undefined;
72
+ model?: string | undefined;
73
+ fillOption?: {
74
+ style: "aspectFit" | "aspectFill";
75
+ } | undefined;
76
+ transition?: {
77
+ type: "fade" | "slideout_left";
78
+ duration: number;
79
+ } | undefined;
80
+ };
81
+ soundEffectParams: {
82
+ provider?: string | undefined;
83
+ model?: string | undefined;
84
+ };
44
85
  $mulmocast: {
45
- version: "1.0";
86
+ version: "1.1";
46
87
  credit?: "closing" | undefined;
47
88
  };
48
89
  canvasSize: {
@@ -50,10 +91,10 @@ export declare const initializeContextFromFiles: (files: FileObject, raiseError:
50
91
  height: number;
51
92
  };
52
93
  speechParams: {
53
- provider: string;
54
94
  speakers: Record<string, {
55
95
  voiceId: string;
56
96
  displayName?: Record<string, string> | undefined;
97
+ isDefault?: boolean | undefined;
57
98
  speechOptions?: {
58
99
  speed?: number | undefined;
59
100
  instruction?: string | undefined;
@@ -61,16 +102,9 @@ export declare const initializeContextFromFiles: (files: FileObject, raiseError:
61
102
  provider?: string | undefined;
62
103
  model?: string | undefined;
63
104
  }>;
64
- model?: string | undefined;
65
105
  };
66
106
  beats: {
67
107
  text: string;
68
- speaker: string;
69
- duration?: number | undefined;
70
- speechOptions?: {
71
- speed?: number | undefined;
72
- instruction?: string | undefined;
73
- } | undefined;
74
108
  image?: {
75
109
  type: "markdown";
76
110
  markdown: string | string[];
@@ -175,6 +209,11 @@ export declare const initializeContextFromFiles: (files: FileObject, raiseError:
175
209
  type: "voice_over";
176
210
  startAt?: number | undefined;
177
211
  } | undefined;
212
+ duration?: number | undefined;
213
+ speechOptions?: {
214
+ speed?: number | undefined;
215
+ instruction?: string | undefined;
216
+ } | undefined;
178
217
  id?: string | undefined;
179
218
  audio?: {
180
219
  type: "audio";
@@ -196,6 +235,7 @@ export declare const initializeContextFromFiles: (files: FileObject, raiseError:
196
235
  source: string;
197
236
  } | undefined;
198
237
  imagePrompt?: string | undefined;
238
+ speaker?: string | undefined;
199
239
  description?: string | undefined;
200
240
  imageParams?: {
201
241
  provider: string;
@@ -228,11 +268,16 @@ export declare const initializeContextFromFiles: (files: FileObject, raiseError:
228
268
  } | undefined;
229
269
  movieParams?: {
230
270
  speed?: number | undefined;
271
+ provider?: string | undefined;
231
272
  model?: string | undefined;
232
273
  fillOption?: {
233
274
  style: "aspectFit" | "aspectFill";
234
275
  } | undefined;
235
276
  } | undefined;
277
+ soundEffectParams?: {
278
+ provider?: string | undefined;
279
+ model?: string | undefined;
280
+ } | undefined;
236
281
  htmlImageParams?: {
237
282
  model?: string | undefined;
238
283
  } | undefined;
@@ -245,6 +290,7 @@ export declare const initializeContextFromFiles: (files: FileObject, raiseError:
245
290
  } | undefined;
246
291
  imageNames?: string[] | undefined;
247
292
  moviePrompt?: string | undefined;
293
+ soundEffectPrompt?: string | undefined;
248
294
  htmlPrompt?: {
249
295
  prompt: string;
250
296
  data?: any;
@@ -255,42 +301,6 @@ export declare const initializeContextFromFiles: (files: FileObject, raiseError:
255
301
  lang?: string | undefined;
256
302
  title?: string | undefined;
257
303
  description?: string | undefined;
258
- imageParams?: {
259
- provider: string;
260
- model?: string | undefined;
261
- style?: string | undefined;
262
- moderation?: string | undefined;
263
- images?: Record<string, {
264
- type: "image";
265
- source: {
266
- url: string;
267
- kind: "url";
268
- } | {
269
- kind: "base64";
270
- data: string;
271
- } | {
272
- text: string;
273
- kind: "text";
274
- } | {
275
- path: string;
276
- kind: "path";
277
- };
278
- } | {
279
- type: "imagePrompt";
280
- prompt: string;
281
- }> | undefined;
282
- } | undefined;
283
- movieParams?: {
284
- provider?: string | undefined;
285
- model?: string | undefined;
286
- fillOption?: {
287
- style: "aspectFit" | "aspectFill";
288
- } | undefined;
289
- transition?: {
290
- type: "fade" | "slideout_left";
291
- duration: number;
292
- } | undefined;
293
- } | undefined;
294
304
  htmlImageParams?: {
295
305
  provider: string;
296
306
  model?: string | undefined;
@@ -333,9 +343,35 @@ export declare const initializeContextFromFiles: (files: FileObject, raiseError:
333
343
  caption: {};
334
344
  html: {};
335
345
  imageReference: {};
346
+ soundEffect: {};
336
347
  };
337
348
  };
338
349
  presentationStyle: {
350
+ imageParams: {
351
+ provider: string;
352
+ model?: string | undefined;
353
+ style?: string | undefined;
354
+ moderation?: string | undefined;
355
+ images?: Record<string, {
356
+ type: "image";
357
+ source: {
358
+ url: string;
359
+ kind: "url";
360
+ } | {
361
+ kind: "base64";
362
+ data: string;
363
+ } | {
364
+ text: string;
365
+ kind: "text";
366
+ } | {
367
+ path: string;
368
+ kind: "path";
369
+ };
370
+ } | {
371
+ type: "imagePrompt";
372
+ prompt: string;
373
+ }> | undefined;
374
+ };
339
375
  audioParams: {
340
376
  padding: number;
341
377
  introPadding: number;
@@ -358,8 +394,23 @@ export declare const initializeContextFromFiles: (files: FileObject, raiseError:
358
394
  kind: "path";
359
395
  } | undefined;
360
396
  };
397
+ movieParams: {
398
+ provider?: string | undefined;
399
+ model?: string | undefined;
400
+ fillOption?: {
401
+ style: "aspectFit" | "aspectFill";
402
+ } | undefined;
403
+ transition?: {
404
+ type: "fade" | "slideout_left";
405
+ duration: number;
406
+ } | undefined;
407
+ };
408
+ soundEffectParams: {
409
+ provider?: string | undefined;
410
+ model?: string | undefined;
411
+ };
361
412
  $mulmocast: {
362
- version: "1.0";
413
+ version: "1.1";
363
414
  credit?: "closing" | undefined;
364
415
  };
365
416
  canvasSize: {
@@ -367,10 +418,10 @@ export declare const initializeContextFromFiles: (files: FileObject, raiseError:
367
418
  height: number;
368
419
  };
369
420
  speechParams: {
370
- provider: string;
371
421
  speakers: Record<string, {
372
422
  voiceId: string;
373
423
  displayName?: Record<string, string> | undefined;
424
+ isDefault?: boolean | undefined;
374
425
  speechOptions?: {
375
426
  speed?: number | undefined;
376
427
  instruction?: string | undefined;
@@ -378,44 +429,7 @@ export declare const initializeContextFromFiles: (files: FileObject, raiseError:
378
429
  provider?: string | undefined;
379
430
  model?: string | undefined;
380
431
  }>;
381
- model?: string | undefined;
382
432
  };
383
- imageParams?: {
384
- provider: string;
385
- model?: string | undefined;
386
- style?: string | undefined;
387
- moderation?: string | undefined;
388
- images?: Record<string, {
389
- type: "image";
390
- source: {
391
- url: string;
392
- kind: "url";
393
- } | {
394
- kind: "base64";
395
- data: string;
396
- } | {
397
- text: string;
398
- kind: "text";
399
- } | {
400
- path: string;
401
- kind: "path";
402
- };
403
- } | {
404
- type: "imagePrompt";
405
- prompt: string;
406
- }> | undefined;
407
- } | undefined;
408
- movieParams?: {
409
- provider?: string | undefined;
410
- model?: string | undefined;
411
- fillOption?: {
412
- style: "aspectFit" | "aspectFill";
413
- } | undefined;
414
- transition?: {
415
- type: "fade" | "slideout_left";
416
- duration: number;
417
- } | undefined;
418
- } | undefined;
419
433
  htmlImageParams?: {
420
434
  provider: string;
421
435
  model?: string | undefined;
@@ -58,6 +58,7 @@ const initSessionState = () => {
58
58
  caption: {},
59
59
  html: {},
60
60
  imageReference: {},
61
+ soundEffect: {},
61
62
  },
62
63
  };
63
64
  };
@@ -84,7 +85,7 @@ export const initializeContextFromFiles = async (files, raiseError, force, capti
84
85
  const currentStudio = readMulmoScriptFile(outputStudioFilePath);
85
86
  try {
86
87
  // validate mulmoStudioSchema. skip if __test_invalid__ is true
87
- const studio = createOrUpdateStudioData(mulmoScript, currentStudio?.mulmoData, fileName, caption);
88
+ const studio = createOrUpdateStudioData(mulmoScript, currentStudio?.mulmoData, fileName, caption, presentationStyle);
88
89
  const multiLingual = getMultiLingual(outputMultilingualFilePath, studio.beats.length);
89
90
  return buildContext(studio, files, presentationStyle, multiLingual, force, lang);
90
91
  }
@@ -1,5 +1,6 @@
1
1
  import ffmpeg from "fluent-ffmpeg";
2
2
  import { GraphAILogger } from "graphai";
3
+ import fs from "fs";
3
4
  export const setFfmpegPath = (ffmpegPath) => {
4
5
  ffmpeg.setFfmpegPath(ffmpegPath);
5
6
  };
@@ -61,6 +62,11 @@ export const FfmpegContextGenerateOutput = (context, output, options = []) => {
61
62
  };
62
63
  export const ffmpegGetMediaDuration = (filePath) => {
63
64
  return new Promise((resolve, reject) => {
65
+ // Only check file existence for local paths, not URLs
66
+ if (!filePath.startsWith("http://") && !filePath.startsWith("https://") && !fs.existsSync(filePath)) {
67
+ reject(new Error(`File not found: ${filePath}`));
68
+ return;
69
+ }
64
70
  ffmpeg.ffprobe(filePath, (err, metadata) => {
65
71
  if (err) {
66
72
  GraphAILogger.info("Error while getting metadata:", err);
@@ -25,7 +25,10 @@ export declare const getAudioArtifactFilePath: (outDirPath: string, fileName: st
25
25
  export declare const getOutputVideoFilePath: (outDirPath: string, fileName: string, lang?: string, caption?: string) => string;
26
26
  export declare const imageSuffix = "p";
27
27
  export declare const getBeatPngImagePath: (context: MulmoStudioContext, index: number) => string;
28
- export declare const getBeatMoviePath: (context: MulmoStudioContext, index: number) => string;
28
+ export declare const getBeatMoviePaths: (context: MulmoStudioContext, index: number) => {
29
+ movieFile: string;
30
+ soundEffectFile: string;
31
+ };
29
32
  export declare const getReferenceImagePath: (context: MulmoStudioContext, key: string, extension: string) => string;
30
33
  export declare const getCaptionImagePath: (context: MulmoStudioContext, index: number) => string;
31
34
  export declare const getOutputPdfFilePath: (outDirPath: string, fileName: string, pdfMode: PDFMode, lang?: string) => string;
package/lib/utils/file.js CHANGED
@@ -87,13 +87,11 @@ export const getBeatPngImagePath = (context, index) => {
87
87
  }
88
88
  return `${imageProjectDirPath}/${index}${imageSuffix}.png`;
89
89
  };
90
- export const getBeatMoviePath = (context, index) => {
90
+ export const getBeatMoviePaths = (context, index) => {
91
91
  const imageProjectDirPath = MulmoStudioContextMethods.getImageProjectDirPath(context);
92
92
  const beat = context.studio.script.beats[index]; // beat could be undefined only in a test case.
93
- if (beat?.id) {
94
- return `${imageProjectDirPath}/${beat.id}.mov`;
95
- }
96
- return `${imageProjectDirPath}/${index}.mov`;
93
+ const filename = beat?.id ? `${beat.id}` : `${index}`;
94
+ return { movieFile: `${imageProjectDirPath}/${filename}.mov`, soundEffectFile: `${imageProjectDirPath}/${filename}_sound.mov` };
97
95
  };
98
96
  export const getReferenceImagePath = (context, key, extension) => {
99
97
  const imageProjectDirPath = MulmoStudioContextMethods.getImageProjectDirPath(context);