mulmocast 1.1.5 → 1.1.6

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 (67) hide show
  1. package/lib/actions/audio.js +10 -1
  2. package/lib/actions/image_agents.d.ts +3 -12
  3. package/lib/actions/image_agents.js +12 -8
  4. package/lib/actions/images.js +2 -1
  5. package/lib/actions/translate.js +13 -31
  6. package/lib/agents/lipsync_replicate_agent.js +10 -3
  7. package/lib/cli/commands/audio/handler.js +1 -1
  8. package/lib/cli/commands/image/handler.js +1 -1
  9. package/lib/cli/commands/movie/handler.js +1 -1
  10. package/lib/cli/commands/pdf/handler.js +1 -1
  11. package/lib/cli/helpers.d.ts +1 -4
  12. package/lib/cli/helpers.js +3 -2
  13. package/lib/mcp/server.js +1 -1
  14. package/lib/methods/mulmo_presentation_style.d.ts +3 -2
  15. package/lib/methods/mulmo_script.js +4 -1
  16. package/lib/methods/mulmo_studio_context.d.ts +1 -0
  17. package/lib/methods/mulmo_studio_context.js +8 -0
  18. package/lib/types/agent.d.ts +1 -0
  19. package/lib/types/schema.d.ts +8 -8
  20. package/lib/types/schema.js +1 -1
  21. package/lib/types/type.d.ts +1 -1
  22. package/lib/utils/const.js +1 -1
  23. package/lib/utils/context.d.ts +376 -34
  24. package/lib/utils/context.js +95 -56
  25. package/lib/utils/filters.d.ts +1 -0
  26. package/lib/utils/filters.js +8 -0
  27. package/lib/utils/preprocess.d.ts +2 -2
  28. package/lib/utils/preprocess.js +3 -3
  29. package/lib/utils/provider2agent.d.ts +3 -2
  30. package/lib/utils/provider2agent.js +20 -2
  31. package/lib/utils/string.d.ts +1 -1
  32. package/lib/utils/string.js +11 -8
  33. package/package.json +1 -1
  34. package/scripts/templates/image_refs.json +1 -0
  35. package/scripts/templates/voice_over.json +1 -0
  36. package/scripts/test/gpt.json +1 -0
  37. package/scripts/test/test1.json +1 -0
  38. package/scripts/test/test_audio.json +1 -0
  39. package/scripts/test/test_audio_instructions.json +1 -0
  40. package/scripts/test/test_beats.json +1 -0
  41. package/scripts/test/test_captions.json +1 -0
  42. package/scripts/test/test_elevenlabs_models.json +1 -0
  43. package/scripts/test/test_hello.json +1 -0
  44. package/scripts/test/test_hello_google.json +1 -0
  45. package/scripts/test/test_html.json +1 -0
  46. package/scripts/test/test_image_refs.json +1 -0
  47. package/scripts/test/test_images.json +1 -0
  48. package/scripts/test/test_lang.json +58 -2
  49. package/scripts/test/test_layout.json +1 -0
  50. package/scripts/test/test_lipsync.json +9 -0
  51. package/scripts/test/test_loop.json +1 -0
  52. package/scripts/test/test_media.json +1 -0
  53. package/scripts/test/test_mixed_providers.json +1 -0
  54. package/scripts/test/test_movie.json +1 -0
  55. package/scripts/test/test_no_audio.json +1 -0
  56. package/scripts/test/test_no_audio_with_credit.json +1 -0
  57. package/scripts/test/test_order.json +1 -0
  58. package/scripts/test/test_order_portrait.json +1 -0
  59. package/scripts/test/test_replicate.json +19 -0
  60. package/scripts/test/test_slideout_left_no_audio.json +1 -0
  61. package/scripts/test/test_spillover.json +1 -0
  62. package/scripts/test/test_transition.json +1 -0
  63. package/scripts/test/test_transition_no_audio.json +1 -0
  64. package/scripts/test/test_video_speed.json +1 -0
  65. package/scripts/test/test_voice_over.json +1 -0
  66. package/scripts/test/test_voices.json +1 -0
  67. package/scripts/templates/image_prompt_only_template.ts +0 -95
@@ -1,9 +1,351 @@
1
1
  import type { MulmoScript, MulmoPresentationStyle, MulmoStudioMultiLingual } from "../types/type.js";
2
2
  import { FileObject } from "../types/index.js";
3
+ export declare const createStudioData: (_mulmoScript: MulmoScript, fileName: string, videoCaptionLang?: string, presentationStyle?: MulmoPresentationStyle | null) => {
4
+ beats: {
5
+ duration?: number | undefined;
6
+ startAt?: number | undefined;
7
+ hash?: string | undefined;
8
+ audioDuration?: number | undefined;
9
+ movieDuration?: number | undefined;
10
+ silenceDuration?: number | undefined;
11
+ hasMovieAudio?: boolean | undefined;
12
+ audioFile?: string | undefined;
13
+ imageFile?: string | undefined;
14
+ movieFile?: string | undefined;
15
+ soundEffectFile?: string | undefined;
16
+ lipSyncFile?: string | undefined;
17
+ captionFile?: string | undefined;
18
+ }[];
19
+ script: {
20
+ lang: string;
21
+ imageParams: {
22
+ provider: string;
23
+ model?: string | undefined;
24
+ style?: string | undefined;
25
+ quality?: string | undefined;
26
+ moderation?: string | undefined;
27
+ images?: Record<string, {
28
+ type: "image";
29
+ source: {
30
+ url: string;
31
+ kind: "url";
32
+ } | {
33
+ kind: "base64";
34
+ data: string;
35
+ } | {
36
+ text: string;
37
+ kind: "text";
38
+ } | {
39
+ path: string;
40
+ kind: "path";
41
+ };
42
+ } | {
43
+ type: "imagePrompt";
44
+ prompt: string;
45
+ }> | undefined;
46
+ };
47
+ audioParams: {
48
+ padding: number;
49
+ introPadding: number;
50
+ closingPadding: number;
51
+ outroPadding: number;
52
+ bgmVolume: number;
53
+ audioVolume: number;
54
+ suppressSpeech: boolean;
55
+ bgm?: {
56
+ url: string;
57
+ kind: "url";
58
+ } | {
59
+ kind: "base64";
60
+ data: string;
61
+ } | {
62
+ text: string;
63
+ kind: "text";
64
+ } | {
65
+ path: string;
66
+ kind: "path";
67
+ } | undefined;
68
+ };
69
+ movieParams: {
70
+ provider?: string | undefined;
71
+ model?: string | undefined;
72
+ fillOption?: {
73
+ style: "aspectFit" | "aspectFill";
74
+ } | undefined;
75
+ transition?: {
76
+ type: "fade" | "slideout_left";
77
+ duration: number;
78
+ } | undefined;
79
+ };
80
+ soundEffectParams: {
81
+ provider?: string | undefined;
82
+ model?: string | undefined;
83
+ };
84
+ $mulmocast: {
85
+ version: "1.1";
86
+ credit?: "closing" | undefined;
87
+ };
88
+ canvasSize: {
89
+ width: number;
90
+ height: number;
91
+ };
92
+ speechParams: {
93
+ speakers: Record<string, {
94
+ voiceId: string;
95
+ lang?: Record<string, {
96
+ voiceId: string;
97
+ displayName?: Record<string, string> | undefined;
98
+ isDefault?: boolean | undefined;
99
+ speechOptions?: {
100
+ speed?: number | undefined;
101
+ instruction?: string | undefined;
102
+ } | undefined;
103
+ provider?: string | undefined;
104
+ model?: string | undefined;
105
+ }> | undefined;
106
+ displayName?: Record<string, string> | undefined;
107
+ isDefault?: boolean | undefined;
108
+ speechOptions?: {
109
+ speed?: number | undefined;
110
+ instruction?: string | undefined;
111
+ } | undefined;
112
+ provider?: string | undefined;
113
+ model?: string | undefined;
114
+ }>;
115
+ };
116
+ beats: {
117
+ text: string;
118
+ image?: {
119
+ type: "markdown";
120
+ markdown: string | string[];
121
+ } | {
122
+ type: "web";
123
+ url: string;
124
+ } | {
125
+ type: "pdf";
126
+ source: {
127
+ url: string;
128
+ kind: "url";
129
+ } | {
130
+ kind: "base64";
131
+ data: string;
132
+ } | {
133
+ text: string;
134
+ kind: "text";
135
+ } | {
136
+ path: string;
137
+ kind: "path";
138
+ };
139
+ } | {
140
+ type: "image";
141
+ source: {
142
+ url: string;
143
+ kind: "url";
144
+ } | {
145
+ kind: "base64";
146
+ data: string;
147
+ } | {
148
+ text: string;
149
+ kind: "text";
150
+ } | {
151
+ path: string;
152
+ kind: "path";
153
+ };
154
+ } | {
155
+ type: "svg";
156
+ source: {
157
+ url: string;
158
+ kind: "url";
159
+ } | {
160
+ kind: "base64";
161
+ data: string;
162
+ } | {
163
+ text: string;
164
+ kind: "text";
165
+ } | {
166
+ path: string;
167
+ kind: "path";
168
+ };
169
+ } | {
170
+ type: "movie";
171
+ source: {
172
+ url: string;
173
+ kind: "url";
174
+ } | {
175
+ kind: "base64";
176
+ data: string;
177
+ } | {
178
+ text: string;
179
+ kind: "text";
180
+ } | {
181
+ path: string;
182
+ kind: "path";
183
+ };
184
+ } | {
185
+ type: "textSlide";
186
+ slide: {
187
+ title: string;
188
+ subtitle?: string | undefined;
189
+ bullets?: string[] | undefined;
190
+ };
191
+ } | {
192
+ type: "chart";
193
+ title: string;
194
+ chartData: Record<string, any>;
195
+ } | {
196
+ code: {
197
+ url: string;
198
+ kind: "url";
199
+ } | {
200
+ kind: "base64";
201
+ data: string;
202
+ } | {
203
+ text: string;
204
+ kind: "text";
205
+ } | {
206
+ path: string;
207
+ kind: "path";
208
+ };
209
+ type: "mermaid";
210
+ title: string;
211
+ appendix?: string[] | undefined;
212
+ } | {
213
+ type: "html_tailwind";
214
+ html: string | string[];
215
+ } | {
216
+ type: "beat";
217
+ id?: string | undefined;
218
+ } | {
219
+ type: "voice_over";
220
+ startAt?: number | undefined;
221
+ } | undefined;
222
+ audio?: {
223
+ type: "audio";
224
+ source: {
225
+ url: string;
226
+ kind: "url";
227
+ } | {
228
+ kind: "base64";
229
+ data: string;
230
+ } | {
231
+ text: string;
232
+ kind: "text";
233
+ } | {
234
+ path: string;
235
+ kind: "path";
236
+ };
237
+ } | {
238
+ type: "midi";
239
+ source: string;
240
+ } | undefined;
241
+ duration?: number | undefined;
242
+ speechOptions?: {
243
+ speed?: number | undefined;
244
+ instruction?: string | undefined;
245
+ } | undefined;
246
+ id?: string | undefined;
247
+ imagePrompt?: string | undefined;
248
+ speaker?: string | undefined;
249
+ description?: string | undefined;
250
+ imageParams?: {
251
+ provider: string;
252
+ model?: string | undefined;
253
+ style?: string | undefined;
254
+ quality?: string | undefined;
255
+ moderation?: string | undefined;
256
+ images?: Record<string, {
257
+ type: "image";
258
+ source: {
259
+ url: string;
260
+ kind: "url";
261
+ } | {
262
+ kind: "base64";
263
+ data: string;
264
+ } | {
265
+ text: string;
266
+ kind: "text";
267
+ } | {
268
+ path: string;
269
+ kind: "path";
270
+ };
271
+ } | {
272
+ type: "imagePrompt";
273
+ prompt: string;
274
+ }> | undefined;
275
+ } | undefined;
276
+ audioParams?: {
277
+ movieVolume: number;
278
+ padding?: number | undefined;
279
+ } | undefined;
280
+ movieParams?: {
281
+ speed?: number | undefined;
282
+ provider?: string | undefined;
283
+ model?: string | undefined;
284
+ fillOption?: {
285
+ style: "aspectFit" | "aspectFill";
286
+ } | undefined;
287
+ } | undefined;
288
+ soundEffectParams?: {
289
+ provider?: string | undefined;
290
+ model?: string | undefined;
291
+ } | undefined;
292
+ lipSyncParams?: {
293
+ provider?: string | undefined;
294
+ model?: string | undefined;
295
+ } | undefined;
296
+ htmlImageParams?: {
297
+ model?: string | undefined;
298
+ } | undefined;
299
+ textSlideParams?: {
300
+ cssStyles: string | string[];
301
+ } | undefined;
302
+ captionParams?: {
303
+ styles: string[];
304
+ lang?: string | undefined;
305
+ } | undefined;
306
+ imageNames?: string[] | undefined;
307
+ moviePrompt?: string | undefined;
308
+ soundEffectPrompt?: string | undefined;
309
+ htmlPrompt?: {
310
+ prompt: string;
311
+ data?: any;
312
+ images?: Record<string, any> | undefined;
313
+ systemPrompt?: string | undefined;
314
+ } | undefined;
315
+ enableLipSync?: boolean | undefined;
316
+ }[];
317
+ title?: string | undefined;
318
+ description?: string | undefined;
319
+ lipSyncParams?: {
320
+ provider?: string | undefined;
321
+ model?: string | undefined;
322
+ } | undefined;
323
+ htmlImageParams?: {
324
+ provider: string;
325
+ model?: string | undefined;
326
+ } | undefined;
327
+ textSlideParams?: {
328
+ cssStyles: string | string[];
329
+ } | undefined;
330
+ captionParams?: {
331
+ styles: string[];
332
+ lang?: string | undefined;
333
+ } | undefined;
334
+ references?: {
335
+ type: string;
336
+ url: string;
337
+ title?: string | undefined;
338
+ description?: string | undefined;
339
+ }[] | undefined;
340
+ imagePath?: string | undefined;
341
+ __test_invalid__?: boolean | undefined;
342
+ };
343
+ filename: string;
344
+ };
3
345
  export declare const fetchScript: (isHttpPath: boolean, mulmoFilePath: string, fileOrUrl: string) => Promise<MulmoScript | null>;
4
346
  export declare const getMultiLingual: (multilingualFilePath: string, studioBeatsLength: number) => MulmoStudioMultiLingual;
5
347
  export declare const getPresentationStyle: (presentationStylePath: string | undefined) => MulmoPresentationStyle | null;
6
- export declare const initializeContextFromFiles: (files: FileObject, raiseError: boolean, force?: boolean, caption?: string, lang?: string) => Promise<{
348
+ export declare const initializeContextFromFiles: (files: FileObject, raiseError: boolean, force?: boolean, captionLang?: string, targetLang?: string) => Promise<{
7
349
  studio: {
8
350
  beats: {
9
351
  duration?: number | undefined;
@@ -21,6 +363,7 @@ export declare const initializeContextFromFiles: (files: FileObject, raiseError:
21
363
  captionFile?: string | undefined;
22
364
  }[];
23
365
  script: {
366
+ lang: string;
24
367
  imageParams: {
25
368
  provider: string;
26
369
  model?: string | undefined;
@@ -317,7 +660,6 @@ export declare const initializeContextFromFiles: (files: FileObject, raiseError:
317
660
  } | undefined;
318
661
  enableLipSync?: boolean | undefined;
319
662
  }[];
320
- lang?: string | undefined;
321
663
  title?: string | undefined;
322
664
  description?: string | undefined;
323
665
  lipSyncParams?: {
@@ -346,30 +688,16 @@ export declare const initializeContextFromFiles: (files: FileObject, raiseError:
346
688
  };
347
689
  filename: string;
348
690
  };
691
+ multiLingual: {
692
+ multiLingualTexts: Record<string, {
693
+ text: string;
694
+ lang: string;
695
+ texts?: string[] | undefined;
696
+ ttsTexts?: string[] | undefined;
697
+ duration?: number | undefined;
698
+ }>;
699
+ }[];
349
700
  fileDirs: FileObject;
350
- force: boolean;
351
- lang: string | undefined;
352
- sessionState: {
353
- inSession: {
354
- audio: boolean;
355
- image: boolean;
356
- video: boolean;
357
- multiLingual: boolean;
358
- caption: boolean;
359
- pdf: boolean;
360
- };
361
- inBeatSession: {
362
- audio: {};
363
- image: {};
364
- movie: {};
365
- multiLingual: {};
366
- caption: {};
367
- html: {};
368
- imageReference: {};
369
- soundEffect: {};
370
- lipSync: {};
371
- };
372
- };
373
701
  presentationStyle: {
374
702
  imageParams: {
375
703
  provider: string;
@@ -482,13 +810,27 @@ export declare const initializeContextFromFiles: (files: FileObject, raiseError:
482
810
  lang?: string | undefined;
483
811
  } | undefined;
484
812
  };
485
- multiLingual: {
486
- multiLingualTexts: Record<string, {
487
- text: string;
488
- lang: string;
489
- texts?: string[] | undefined;
490
- ttsTexts?: string[] | undefined;
491
- duration?: number | undefined;
492
- }>;
493
- }[];
813
+ sessionState: {
814
+ inSession: {
815
+ audio: boolean;
816
+ image: boolean;
817
+ video: boolean;
818
+ multiLingual: boolean;
819
+ caption: boolean;
820
+ pdf: boolean;
821
+ };
822
+ inBeatSession: {
823
+ audio: {};
824
+ image: {};
825
+ movie: {};
826
+ multiLingual: {};
827
+ caption: {};
828
+ html: {};
829
+ imageReference: {};
830
+ soundEffect: {};
831
+ lipSync: {};
832
+ };
833
+ };
834
+ force: boolean;
835
+ lang: string;
494
836
  } | null>;
@@ -1,44 +1,28 @@
1
1
  import { GraphAILogger } from "graphai";
2
2
  import fs from "fs";
3
3
  import { readMulmoScriptFile, fetchMulmoScriptFile } from "./file.js";
4
- import { createOrUpdateStudioData } from "./preprocess.js";
4
+ import { mulmoStudioSchema, mulmoCaptionParamsSchema } from "../types/index.js";
5
+ import { MulmoPresentationStyleMethods, MulmoScriptMethods } from "../methods/index.js";
5
6
  import { mulmoPresentationStyleSchema, mulmoStudioMultiLingualSchema } from "../types/index.js";
6
- export const fetchScript = async (isHttpPath, mulmoFilePath, fileOrUrl) => {
7
- if (isHttpPath) {
8
- const res = await fetchMulmoScriptFile(fileOrUrl);
9
- if (!res.result || !res.script) {
10
- GraphAILogger.info(`ERROR: HTTP error! ${res.status} ${fileOrUrl}`);
11
- return null;
12
- }
13
- return res.script;
14
- }
15
- if (!fs.existsSync(mulmoFilePath)) {
16
- GraphAILogger.info(`ERROR: File not exists ${mulmoFilePath}`);
17
- return null;
18
- }
19
- return readMulmoScriptFile(mulmoFilePath, "ERROR: File does not exist " + mulmoFilePath)?.mulmoData ?? null;
20
- };
21
- export const getMultiLingual = (multilingualFilePath, studioBeatsLength) => {
22
- if (fs.existsSync(multilingualFilePath)) {
23
- const jsonData = readMulmoScriptFile(multilingualFilePath, "ERROR: File does not exist " + multilingualFilePath)?.mulmoData ?? null;
24
- const dataSet = mulmoStudioMultiLingualSchema.parse(jsonData);
25
- while (dataSet.length < studioBeatsLength) {
26
- dataSet.push({ multiLingualTexts: {} });
27
- }
28
- dataSet.length = studioBeatsLength;
29
- return dataSet;
30
- }
31
- return [...Array(studioBeatsLength)].map(() => ({ multiLingualTexts: {} }));
32
- };
33
- export const getPresentationStyle = (presentationStylePath) => {
34
- if (presentationStylePath) {
35
- if (!fs.existsSync(presentationStylePath)) {
36
- throw new Error(`ERROR: File not exists ${presentationStylePath}`);
37
- }
38
- const jsonData = readMulmoScriptFile(presentationStylePath, "ERROR: File does not exist " + presentationStylePath)?.mulmoData ?? null;
39
- return mulmoPresentationStyleSchema.parse(jsonData);
40
- }
41
- return null;
7
+ const mulmoCredit = (speaker) => {
8
+ return {
9
+ speaker,
10
+ text: "",
11
+ image: {
12
+ type: "image",
13
+ source: {
14
+ kind: "url",
15
+ url: "https://github.com/receptron/mulmocast-cli/raw/refs/heads/main/assets/images/mulmocast_credit.png",
16
+ },
17
+ },
18
+ audio: {
19
+ type: "audio",
20
+ source: {
21
+ kind: "url",
22
+ url: "https://github.com/receptron/mulmocast-cli/raw/refs/heads/main/assets/audio/silent300.mp3",
23
+ },
24
+ },
25
+ };
42
26
  };
43
27
  const initSessionState = () => {
44
28
  return {
@@ -63,32 +47,87 @@ const initSessionState = () => {
63
47
  },
64
48
  };
65
49
  };
66
- const buildContext = (studio, files, presentationStyle, multiLingual, force, lang) => {
67
- return {
68
- studio,
69
- fileDirs: files,
70
- force: Boolean(force),
71
- lang,
72
- sessionState: initSessionState(),
73
- presentationStyle: presentationStyle ?? studio.script,
74
- multiLingual,
75
- };
50
+ export const createStudioData = (_mulmoScript, fileName, videoCaptionLang, presentationStyle) => {
51
+ // validate and insert default value
52
+ const mulmoScript = _mulmoScript.__test_invalid__ ? _mulmoScript : MulmoScriptMethods.validate(_mulmoScript);
53
+ // We need to parse it to fill default values
54
+ const studio = mulmoStudioSchema.parse({
55
+ script: mulmoScript,
56
+ filename: fileName,
57
+ beats: [...Array(mulmoScript.beats.length)].map(() => ({})),
58
+ });
59
+ // TODO: Move this code out of this function later
60
+ // Addition cloing credit
61
+ if (mulmoScript.$mulmocast.credit === "closing") {
62
+ const defaultSpeaker = MulmoPresentationStyleMethods.getDefaultSpeaker(presentationStyle ?? studio.script);
63
+ mulmoScript.beats.push(mulmoCredit(mulmoScript.beats[0].speaker ?? defaultSpeaker)); // First speaker
64
+ }
65
+ studio.script = MulmoScriptMethods.validate(mulmoScript); // update the script
66
+ studio.beats = studio.script.beats.map((_, index) => studio.beats[index] ?? {});
67
+ if (videoCaptionLang) {
68
+ studio.script.captionParams = mulmoCaptionParamsSchema.parse({
69
+ ...(studio.script.captionParams ?? {}),
70
+ lang: videoCaptionLang,
71
+ });
72
+ }
73
+ return studio;
74
+ };
75
+ export const fetchScript = async (isHttpPath, mulmoFilePath, fileOrUrl) => {
76
+ if (isHttpPath) {
77
+ const res = await fetchMulmoScriptFile(fileOrUrl);
78
+ if (!res.result || !res.script) {
79
+ GraphAILogger.info(`ERROR: HTTP error! ${res.status} ${fileOrUrl}`);
80
+ return null;
81
+ }
82
+ return res.script;
83
+ }
84
+ if (!fs.existsSync(mulmoFilePath)) {
85
+ GraphAILogger.info(`ERROR: File not exists ${mulmoFilePath}`);
86
+ return null;
87
+ }
88
+ return readMulmoScriptFile(mulmoFilePath, "ERROR: File does not exist " + mulmoFilePath)?.mulmoData ?? null;
89
+ };
90
+ export const getMultiLingual = (multilingualFilePath, studioBeatsLength) => {
91
+ if (!fs.existsSync(multilingualFilePath)) {
92
+ return [...Array(studioBeatsLength)].map(() => ({ multiLingualTexts: {} }));
93
+ }
94
+ const jsonData = readMulmoScriptFile(multilingualFilePath, "ERROR: File does not exist " + multilingualFilePath)?.mulmoData ?? null;
95
+ const dataSet = mulmoStudioMultiLingualSchema.parse(jsonData);
96
+ while (dataSet.length < studioBeatsLength) {
97
+ dataSet.push({ multiLingualTexts: {} });
98
+ }
99
+ dataSet.length = studioBeatsLength;
100
+ return dataSet;
101
+ };
102
+ export const getPresentationStyle = (presentationStylePath) => {
103
+ if (!presentationStylePath) {
104
+ return null;
105
+ }
106
+ if (!fs.existsSync(presentationStylePath)) {
107
+ throw new Error(`ERROR: File not exists ${presentationStylePath}`);
108
+ }
109
+ const jsonData = readMulmoScriptFile(presentationStylePath, "ERROR: File does not exist " + presentationStylePath)?.mulmoData ?? null;
110
+ return mulmoPresentationStyleSchema.parse(jsonData);
76
111
  };
77
- export const initializeContextFromFiles = async (files, raiseError, force, caption, lang) => {
78
- const { fileName, isHttpPath, fileOrUrl, mulmoFilePath, outputStudioFilePath, presentationStylePath, outputMultilingualFilePath } = files;
79
- // read mulmoScript, presentationStyle, currentStudio from files
112
+ export const initializeContextFromFiles = async (files, raiseError, force, captionLang, targetLang) => {
113
+ const { fileName, isHttpPath, fileOrUrl, mulmoFilePath, presentationStylePath, outputMultilingualFilePath } = files;
80
114
  const mulmoScript = await fetchScript(isHttpPath, mulmoFilePath, fileOrUrl);
81
115
  if (!mulmoScript) {
82
116
  return null;
83
117
  }
84
- const presentationStyle = getPresentationStyle(presentationStylePath);
85
- // Create or update MulmoStudio file with MulmoScript
86
- const currentStudio = readMulmoScriptFile(outputStudioFilePath);
87
118
  try {
88
- // validate mulmoStudioSchema. skip if __test_invalid__ is true
89
- const studio = createOrUpdateStudioData(mulmoScript, currentStudio?.mulmoData, fileName, caption, presentationStyle);
119
+ const presentationStyle = getPresentationStyle(presentationStylePath);
120
+ const studio = createStudioData(mulmoScript, fileName, captionLang, presentationStyle);
90
121
  const multiLingual = getMultiLingual(outputMultilingualFilePath, studio.beats.length);
91
- return buildContext(studio, files, presentationStyle, multiLingual, force, lang);
122
+ return {
123
+ studio,
124
+ multiLingual,
125
+ fileDirs: files,
126
+ presentationStyle: presentationStyle ?? studio.script,
127
+ sessionState: initSessionState(),
128
+ force: Boolean(force),
129
+ lang: targetLang ?? studio.script.lang, // This lang is target Language. studio.lang is default Language
130
+ };
92
131
  }
93
132
  catch (error) {
94
133
  GraphAILogger.info(`Error: invalid MulmoScript Schema: ${isHttpPath ? fileOrUrl : mulmoFilePath} \n ${error}`);
@@ -1,4 +1,5 @@
1
1
  import "dotenv/config";
2
2
  import type { AgentFilterFunction } from "graphai";
3
+ export declare const nijovoiceTextAgentFilter: AgentFilterFunction;
3
4
  export declare const fileCacheAgentFilter: AgentFilterFunction;
4
5
  export declare const browserlessCacheGenerator: (cacheDir: string) => AgentFilterFunction;
@@ -6,6 +6,14 @@ import { GraphAILogger } from "graphai";
6
6
  import { writingMessage } from "./file.js";
7
7
  import { text2hash } from "./utils.js";
8
8
  import { MulmoStudioContextMethods } from "../methods/mulmo_studio_context.js";
9
+ import { replacementsJa, replacePairsJa } from "../utils/string.js";
10
+ export const nijovoiceTextAgentFilter = async (context, next) => {
11
+ const { text, provider, lang } = context.namedInputs;
12
+ if (provider === "nijivoice" && lang === "ja") {
13
+ context.namedInputs.text = replacePairsJa(replacementsJa)(text);
14
+ }
15
+ return next(context);
16
+ };
9
17
  export const fileCacheAgentFilter = async (context, next) => {
10
18
  const { force, file, index, mulmoContext, sessionType } = context.namedInputs.cache;
11
19
  const shouldUseCache = async () => {
@@ -1,5 +1,5 @@
1
1
  import { MulmoStudio, MulmoScript, MulmoPresentationStyle } from "../types/index.js";
2
- export declare const createOrUpdateStudioData: (_mulmoScript: MulmoScript, currentStudio: MulmoStudio | undefined, fileName: string, videoCaption?: string, presentationStyle?: MulmoPresentationStyle | null) => {
2
+ export declare const createOrUpdateStudioData: (_mulmoScript: MulmoScript, currentStudio: MulmoStudio | undefined, fileName: string, videoCaptionLang?: string, presentationStyle?: MulmoPresentationStyle | null) => {
3
3
  beats: {
4
4
  duration?: number | undefined;
5
5
  startAt?: number | undefined;
@@ -16,6 +16,7 @@ export declare const createOrUpdateStudioData: (_mulmoScript: MulmoScript, curre
16
16
  captionFile?: string | undefined;
17
17
  }[];
18
18
  script: {
19
+ lang: string;
19
20
  imageParams: {
20
21
  provider: string;
21
22
  model?: string | undefined;
@@ -312,7 +313,6 @@ export declare const createOrUpdateStudioData: (_mulmoScript: MulmoScript, curre
312
313
  } | undefined;
313
314
  enableLipSync?: boolean | undefined;
314
315
  }[];
315
- lang?: string | undefined;
316
316
  title?: string | undefined;
317
317
  description?: string | undefined;
318
318
  lipSyncParams?: {
@@ -37,7 +37,7 @@ const mulmoCredit = (speaker) => {
37
37
  },
38
38
  };
39
39
  };
40
- export const createOrUpdateStudioData = (_mulmoScript, currentStudio, fileName, videoCaption, presentationStyle) => {
40
+ export const createOrUpdateStudioData = (_mulmoScript, currentStudio, fileName, videoCaptionLang, presentationStyle) => {
41
41
  const mulmoScript = _mulmoScript.__test_invalid__ ? _mulmoScript : MulmoScriptMethods.validate(_mulmoScript); // validate and insert default value
42
42
  const studio = rebuildStudio(currentStudio, mulmoScript, fileName);
43
43
  // TODO: Move this code out of this function later
@@ -48,10 +48,10 @@ export const createOrUpdateStudioData = (_mulmoScript, currentStudio, fileName,
48
48
  }
49
49
  studio.script = MulmoScriptMethods.validate(mulmoScript); // update the script
50
50
  studio.beats = studio.script.beats.map((_, index) => studio.beats[index] ?? {});
51
- if (videoCaption) {
51
+ if (videoCaptionLang) {
52
52
  studio.script.captionParams = mulmoCaptionParamsSchema.parse({
53
53
  ...(studio.script.captionParams ?? {}),
54
- lang: videoCaption,
54
+ lang: videoCaptionLang,
55
55
  });
56
56
  }
57
57
  return studio;