mulmocast 0.0.26 → 0.0.28

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.
package/README.md CHANGED
@@ -173,7 +173,7 @@ DEFAULT_OPENAI_IMAGE_MODEL=gpt-image-1 # required for high-quality Ghibli-style
173
173
 
174
174
  ### Step 2: Generate a Ghibli-style MulmoScript
175
175
  ```bash
176
- mulmo tool scripting -i -t ghibli_strips -o ./ -s story
176
+ mulmo tool scripting -i -t ghibli_comic -o ./ -s story
177
177
  ```
178
178
  This will initiate an interactive conversation with the AI to create your Ghibli-inspired story. Once completed, a JSON file (e.g., `story-1747834931950.json`) will be generated.
179
179
 
@@ -32,7 +32,7 @@ const getAudioPath = (context, beat, audioFile) => {
32
32
  }
33
33
  throw new Error("Invalid audio source");
34
34
  }
35
- if (beat.text === undefined || beat.text === "") {
35
+ if (beat.text === undefined || beat.text === "" || context.studio.script.audioParams.suppressSpeech) {
36
36
  return undefined; // It indicates that the audio is not needed.
37
37
  }
38
38
  return audioFile;
@@ -372,13 +372,11 @@ const prepareGenerateImages = async (context) => {
372
372
  const imageProjectDirPath = MulmoStudioContextMethods.getImageProjectDirPath(context);
373
373
  const outDirPath = MulmoStudioContextMethods.getOutDirPath(context);
374
374
  mkdir(imageProjectDirPath);
375
- const imageAgentInfo = MulmoPresentationStyleMethods.getImageAgentInfo(context.presentationStyle, context.dryRun);
375
+ const imageAgentInfo = MulmoPresentationStyleMethods.getImageAgentInfo(context.presentationStyle);
376
376
  const htmlImageAgentInfo = MulmoPresentationStyleMethods.getHtmlImageAgentInfo(context.presentationStyle);
377
377
  const imageRefs = await getImageRefs(context);
378
378
  // Determine movie agent based on provider
379
379
  const getMovieAgent = () => {
380
- if (context.dryRun)
381
- return "mediaMockAgent";
382
380
  const provider = context.presentationStyle.movieParams?.provider ?? "google";
383
381
  switch (provider) {
384
382
  case "replicate":
@@ -7,8 +7,6 @@ export declare const builder: (yargs: Argv) => Argv<{
7
7
  l: string | undefined;
8
8
  } & {
9
9
  f: boolean;
10
- } & {
11
- dryRun: boolean;
12
10
  } & {
13
11
  p: string | undefined;
14
12
  } & {
@@ -7,8 +7,6 @@ export declare const builder: (yargs: Argv) => Argv<{
7
7
  l: string | undefined;
8
8
  } & {
9
9
  f: boolean;
10
- } & {
11
- dryRun: boolean;
12
10
  } & {
13
11
  p: string | undefined;
14
12
  } & {
@@ -7,8 +7,6 @@ export declare const builder: (yargs: Argv) => Argv<{
7
7
  l: string | undefined;
8
8
  } & {
9
9
  f: boolean;
10
- } & {
11
- dryRun: boolean;
12
10
  } & {
13
11
  p: string | undefined;
14
12
  } & {
@@ -7,8 +7,6 @@ export declare const builder: (yargs: Argv) => Argv<{
7
7
  l: string | undefined;
8
8
  } & {
9
9
  f: boolean;
10
- } & {
11
- dryRun: boolean;
12
10
  } & {
13
11
  p: string | undefined;
14
12
  } & {
@@ -7,8 +7,6 @@ export declare const builder: (yargs: Argv) => Argv<import("yargs").Omit<{
7
7
  l: string | undefined;
8
8
  } & {
9
9
  f: boolean;
10
- } & {
11
- dryRun: boolean;
12
10
  } & {
13
11
  p: string | undefined;
14
12
  } & {
@@ -7,8 +7,6 @@ export declare const commonOptions: (yargs: Argv) => Argv<{
7
7
  l: string | undefined;
8
8
  } & {
9
9
  f: boolean;
10
- } & {
11
- dryRun: boolean;
12
10
  } & {
13
11
  p: string | undefined;
14
12
  } & {
package/lib/cli/common.js CHANGED
@@ -25,11 +25,6 @@ export const commonOptions = (yargs) => {
25
25
  describe: "Force regenerate",
26
26
  type: "boolean",
27
27
  default: false,
28
- })
29
- .option("dryRun", {
30
- describe: "Dry run",
31
- type: "boolean",
32
- default: false,
33
28
  })
34
29
  .option("p", {
35
30
  alias: "presentationStyle",
@@ -1,20 +1,10 @@
1
- import type { MulmoScript, MulmoStudioContext, MulmoPresentationStyle, MulmoStudioMultiLingual } from "../types/type.js";
2
1
  import type { CliArgs } from "../types/cli_types.js";
2
+ import { FileObject, InitOptions, MulmoStudioContext } from "../types/index.js";
3
+ export declare const runTranslateIfNeeded: (context: MulmoStudioContext, argv: {
4
+ l?: string;
5
+ c?: string;
6
+ }) => Promise<void>;
3
7
  export declare const setGraphAILogger: (verbose: boolean | undefined, logValues?: Record<string, unknown>) => void;
4
- export interface FileObject {
5
- baseDirPath: string;
6
- mulmoFilePath: string;
7
- mulmoFileDirPath: string;
8
- outDirPath: string;
9
- imageDirPath: string;
10
- audioDirPath: string;
11
- isHttpPath: boolean;
12
- fileOrUrl: string;
13
- outputStudioFilePath: string;
14
- outputMultilingualFilePath: string;
15
- presentationStylePath: string | undefined;
16
- fileName: string;
17
- }
18
8
  export declare const getFileObject: (args: {
19
9
  basedir?: string;
20
10
  outdir?: string;
@@ -23,22 +13,4 @@ export declare const getFileObject: (args: {
23
13
  presentationStyle?: string;
24
14
  file: string;
25
15
  }) => FileObject;
26
- export declare const fetchScript: (isHttpPath: boolean, mulmoFilePath: string, fileOrUrl: string) => Promise<MulmoScript | null>;
27
- export declare const getMultiLingual: (multilingualFilePath: string, beatsLength: number) => MulmoStudioMultiLingual;
28
- export declare const getPresentationStyle: (presentationStylePath: string | undefined) => MulmoPresentationStyle | null;
29
- type InitOptions = {
30
- b?: string;
31
- o?: string;
32
- i?: string;
33
- a?: string;
34
- file?: string;
35
- l?: string;
36
- c?: string;
37
- p?: string;
38
- };
39
- export declare const initializeContext: (argv: CliArgs<InitOptions>) => Promise<MulmoStudioContext | null>;
40
- export declare const runTranslateIfNeeded: (context: MulmoStudioContext, argv: {
41
- l?: string;
42
- c?: string;
43
- }) => Promise<void>;
44
- export {};
16
+ export declare const initializeContext: (argv: CliArgs<InitOptions>, raiseError?: boolean) => Promise<MulmoStudioContext | null>;
@@ -2,12 +2,17 @@ import { GraphAILogger } from "graphai";
2
2
  import fs from "fs";
3
3
  import path from "path";
4
4
  import clipboardy from "clipboardy";
5
- import { getBaseDirPath, getFullPath, readMulmoScriptFile, fetchMulmoScriptFile, getOutputStudioFilePath, resolveDirPath, mkdir, getOutputMultilingualFilePath, generateTimestampedFileName, } from "../utils/file.js";
5
+ import { getBaseDirPath, getFullPath, getOutputStudioFilePath, resolveDirPath, mkdir, getOutputMultilingualFilePath, generateTimestampedFileName, } from "../utils/file.js";
6
6
  import { isHttp } from "../utils/utils.js";
7
- import { createOrUpdateStudioData } from "../utils/preprocess.js";
8
7
  import { outDirName, imageDirName, audioDirName } from "../utils/const.js";
9
8
  import { translate } from "../actions/translate.js";
10
- import { mulmoCaptionParamsSchema, mulmoPresentationStyleSchema, mulmoStudioMultiLingualSchema } from "../types/schema.js";
9
+ import { initializeContextFromFiles } from "../utils/context.js";
10
+ export const runTranslateIfNeeded = async (context, argv) => {
11
+ if (argv.l || context.studio.script.captionParams?.lang) {
12
+ GraphAILogger.log("run translate");
13
+ await translate(context);
14
+ }
15
+ };
11
16
  export const setGraphAILogger = (verbose, logValues) => {
12
17
  if (verbose) {
13
18
  if (logValues) {
@@ -63,44 +68,7 @@ export const getFileObject = (args) => {
63
68
  fileName,
64
69
  };
65
70
  };
66
- export const fetchScript = async (isHttpPath, mulmoFilePath, fileOrUrl) => {
67
- if (isHttpPath) {
68
- const res = await fetchMulmoScriptFile(fileOrUrl);
69
- if (!res.result || !res.script) {
70
- GraphAILogger.info(`ERROR: HTTP error! ${res.status} ${fileOrUrl}`);
71
- return null;
72
- }
73
- return res.script;
74
- }
75
- if (!fs.existsSync(mulmoFilePath)) {
76
- GraphAILogger.info(`ERROR: File not exists ${mulmoFilePath}`);
77
- return null;
78
- }
79
- return readMulmoScriptFile(mulmoFilePath, "ERROR: File does not exist " + mulmoFilePath)?.mulmoData ?? null;
80
- };
81
- export const getMultiLingual = (multilingualFilePath, beatsLength) => {
82
- if (fs.existsSync(multilingualFilePath)) {
83
- const jsonData = readMulmoScriptFile(multilingualFilePath, "ERROR: File does not exist " + multilingualFilePath)?.mulmoData ?? null;
84
- const dataSet = mulmoStudioMultiLingualSchema.parse(jsonData);
85
- while (dataSet.length < beatsLength) {
86
- dataSet.push({ multiLingualTexts: {} });
87
- }
88
- dataSet.length = beatsLength;
89
- return dataSet;
90
- }
91
- return [...Array(beatsLength)].map(() => ({ multiLingualTexts: {} }));
92
- };
93
- export const getPresentationStyle = (presentationStylePath) => {
94
- if (presentationStylePath) {
95
- if (!fs.existsSync(presentationStylePath)) {
96
- throw new Error(`ERROR: File not exists ${presentationStylePath}`);
97
- }
98
- const jsonData = readMulmoScriptFile(presentationStylePath, "ERROR: File does not exist " + presentationStylePath)?.mulmoData ?? null;
99
- return mulmoPresentationStyleSchema.parse(jsonData);
100
- }
101
- return null;
102
- };
103
- export const initializeContext = async (argv) => {
71
+ export const initializeContext = async (argv, raiseError = false) => {
104
72
  const files = getFileObject({
105
73
  basedir: argv.b,
106
74
  outdir: argv.o,
@@ -109,62 +77,6 @@ export const initializeContext = async (argv) => {
109
77
  presentationStyle: argv.p,
110
78
  file: argv.file ?? "",
111
79
  });
112
- const { fileName, isHttpPath, fileOrUrl, mulmoFilePath, outputStudioFilePath, presentationStylePath, outputMultilingualFilePath } = files;
113
- setGraphAILogger(argv.v, {
114
- files,
115
- });
116
- const mulmoScript = await fetchScript(isHttpPath, mulmoFilePath, fileOrUrl);
117
- if (!mulmoScript) {
118
- return null;
119
- }
120
- const presentationStyle = getPresentationStyle(presentationStylePath);
121
- // Create or update MulmoStudio file with MulmoScript
122
- const currentStudio = readMulmoScriptFile(outputStudioFilePath);
123
- try {
124
- // validate mulmoStudioSchema. skip if __test_invalid__ is true
125
- const studio = createOrUpdateStudioData(mulmoScript, currentStudio?.mulmoData, fileName);
126
- const multiLingual = getMultiLingual(outputMultilingualFilePath, studio.beats.length);
127
- if (argv.c) {
128
- studio.script.captionParams = mulmoCaptionParamsSchema.parse({
129
- ...(studio.script.captionParams ?? {}),
130
- lang: argv.c,
131
- });
132
- }
133
- return {
134
- studio,
135
- fileDirs: files,
136
- force: Boolean(argv.f),
137
- dryRun: Boolean(argv.dryRun),
138
- lang: argv.l,
139
- sessionState: {
140
- inSession: {
141
- audio: false,
142
- image: false,
143
- video: false,
144
- multiLingual: false,
145
- caption: false,
146
- pdf: false,
147
- },
148
- inBeatSession: {
149
- audio: {},
150
- image: {},
151
- movie: {},
152
- multiLingual: {},
153
- caption: {},
154
- },
155
- },
156
- presentationStyle: presentationStyle ?? studio.script,
157
- multiLingual,
158
- };
159
- }
160
- catch (error) {
161
- GraphAILogger.info(`Error: invalid MulmoScript Schema: ${isHttpPath ? fileOrUrl : mulmoFilePath} \n ${error}`);
162
- return null;
163
- }
164
- };
165
- export const runTranslateIfNeeded = async (context, argv) => {
166
- if (argv.l || context.studio.script.captionParams?.lang) {
167
- GraphAILogger.log("run translate");
168
- await translate(context);
169
- }
80
+ setGraphAILogger(Boolean(argv.v), { files });
81
+ return await initializeContextFromFiles(files, raiseError, Boolean(argv.f), argv.c, argv.l);
170
82
  };
package/lib/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export * from "./actions/index.js";
2
2
  export * from "./cli/helpers.js";
3
3
  export * from "./utils/file.js";
4
+ export * from "./utils/ffmpeg_utils.js";
4
5
  export * from "./methods/index.js";
5
6
  export * from "./agents/index.js";
6
7
  export * from "./types/index.js";
package/lib/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  export * from "./actions/index.js";
2
2
  export * from "./cli/helpers.js";
3
3
  export * from "./utils/file.js";
4
+ export * from "./utils/ffmpeg_utils.js";
4
5
  export * from "./methods/index.js";
5
6
  export * from "./agents/index.js";
6
7
  export * from "./types/index.js";
@@ -9,7 +9,7 @@ export declare const MulmoPresentationStyleMethods: {
9
9
  getSpeaker(presentationStyle: MulmoPresentationStyle, beat: MulmoBeat): SpeakerData;
10
10
  getProvider(presentationStyle: MulmoPresentationStyle, beat: MulmoBeat): Text2SpeechProvider;
11
11
  getVoiceId(presentationStyle: MulmoPresentationStyle, beat: MulmoBeat): string;
12
- getImageAgentInfo(presentationStyle: MulmoPresentationStyle, dryRun?: boolean): Text2ImageAgentInfo;
12
+ getImageAgentInfo(presentationStyle: MulmoPresentationStyle): Text2ImageAgentInfo;
13
13
  getHtmlImageAgentInfo(presentationStyle: MulmoPresentationStyle): Text2HtmlAgentInfo;
14
14
  getImageType(_: MulmoPresentationStyle, beat: MulmoBeat): BeatMediaType;
15
15
  };
@@ -57,7 +57,7 @@ export const MulmoPresentationStyleMethods = {
57
57
  const speaker = MulmoPresentationStyleMethods.getSpeaker(presentationStyle, beat);
58
58
  return speaker.voiceId;
59
59
  },
60
- getImageAgentInfo(presentationStyle, dryRun = false) {
60
+ getImageAgentInfo(presentationStyle) {
61
61
  // Notice that we copy imageParams from presentationStyle and update
62
62
  // provider and model appropriately.
63
63
  const provider = text2ImageProviderSchema.parse(presentationStyle.imageParams?.provider);
@@ -66,7 +66,7 @@ export const MulmoPresentationStyleMethods = {
66
66
  };
67
67
  return {
68
68
  provider,
69
- agent: dryRun ? "mediaMockAgent" : provider === "google" ? "imageGoogleAgent" : "imageOpenaiAgent",
69
+ agent: provider === "google" ? "imageGoogleAgent" : "imageOpenaiAgent",
70
70
  imageParams: { ...defaultImageParams, ...presentationStyle.imageParams },
71
71
  };
72
72
  },
@@ -1146,6 +1146,7 @@ export declare const audioParamsSchema: z.ZodObject<{
1146
1146
  }>]>>;
1147
1147
  bgmVolume: z.ZodDefault<z.ZodNumber>;
1148
1148
  audioVolume: z.ZodDefault<z.ZodNumber>;
1149
+ suppressSpeech: z.ZodDefault<z.ZodBoolean>;
1149
1150
  }, "strict", z.ZodTypeAny, {
1150
1151
  padding: number;
1151
1152
  introPadding: number;
@@ -1153,6 +1154,7 @@ export declare const audioParamsSchema: z.ZodObject<{
1153
1154
  outroPadding: number;
1154
1155
  bgmVolume: number;
1155
1156
  audioVolume: number;
1157
+ suppressSpeech: boolean;
1156
1158
  bgm?: {
1157
1159
  url: string;
1158
1160
  kind: "url";
@@ -1186,6 +1188,7 @@ export declare const audioParamsSchema: z.ZodObject<{
1186
1188
  } | undefined;
1187
1189
  bgmVolume?: number | undefined;
1188
1190
  audioVolume?: number | undefined;
1191
+ suppressSpeech?: boolean | undefined;
1189
1192
  }>;
1190
1193
  export declare const htmlPromptParamsSchema: z.ZodObject<{
1191
1194
  systemPrompt: z.ZodOptional<z.ZodDefault<z.ZodString>>;
@@ -2711,6 +2714,7 @@ export declare const mulmoPresentationStyleSchema: z.ZodObject<{
2711
2714
  }>]>>;
2712
2715
  bgmVolume: z.ZodDefault<z.ZodNumber>;
2713
2716
  audioVolume: z.ZodDefault<z.ZodNumber>;
2717
+ suppressSpeech: z.ZodDefault<z.ZodBoolean>;
2714
2718
  }, "strict", z.ZodTypeAny, {
2715
2719
  padding: number;
2716
2720
  introPadding: number;
@@ -2718,6 +2722,7 @@ export declare const mulmoPresentationStyleSchema: z.ZodObject<{
2718
2722
  outroPadding: number;
2719
2723
  bgmVolume: number;
2720
2724
  audioVolume: number;
2725
+ suppressSpeech: boolean;
2721
2726
  bgm?: {
2722
2727
  url: string;
2723
2728
  kind: "url";
@@ -2751,6 +2756,7 @@ export declare const mulmoPresentationStyleSchema: z.ZodObject<{
2751
2756
  } | undefined;
2752
2757
  bgmVolume?: number | undefined;
2753
2758
  audioVolume?: number | undefined;
2759
+ suppressSpeech?: boolean | undefined;
2754
2760
  }>>;
2755
2761
  }, "strip", z.ZodTypeAny, {
2756
2762
  audioParams: {
@@ -2760,6 +2766,7 @@ export declare const mulmoPresentationStyleSchema: z.ZodObject<{
2760
2766
  outroPadding: number;
2761
2767
  bgmVolume: number;
2762
2768
  audioVolume: number;
2769
+ suppressSpeech: boolean;
2763
2770
  bgm?: {
2764
2771
  url: string;
2765
2772
  kind: "url";
@@ -2885,6 +2892,7 @@ export declare const mulmoPresentationStyleSchema: z.ZodObject<{
2885
2892
  } | undefined;
2886
2893
  bgmVolume?: number | undefined;
2887
2894
  audioVolume?: number | undefined;
2895
+ suppressSpeech?: boolean | undefined;
2888
2896
  } | undefined;
2889
2897
  movieParams?: {
2890
2898
  provider?: "openai" | "google" | "replicate" | undefined;
@@ -3250,6 +3258,7 @@ export declare const mulmoScriptSchema: z.ZodObject<{
3250
3258
  }>]>>;
3251
3259
  bgmVolume: z.ZodDefault<z.ZodNumber>;
3252
3260
  audioVolume: z.ZodDefault<z.ZodNumber>;
3261
+ suppressSpeech: z.ZodDefault<z.ZodBoolean>;
3253
3262
  }, "strict", z.ZodTypeAny, {
3254
3263
  padding: number;
3255
3264
  introPadding: number;
@@ -3257,6 +3266,7 @@ export declare const mulmoScriptSchema: z.ZodObject<{
3257
3266
  outroPadding: number;
3258
3267
  bgmVolume: number;
3259
3268
  audioVolume: number;
3269
+ suppressSpeech: boolean;
3260
3270
  bgm?: {
3261
3271
  url: string;
3262
3272
  kind: "url";
@@ -3290,6 +3300,7 @@ export declare const mulmoScriptSchema: z.ZodObject<{
3290
3300
  } | undefined;
3291
3301
  bgmVolume?: number | undefined;
3292
3302
  audioVolume?: number | undefined;
3303
+ suppressSpeech?: boolean | undefined;
3293
3304
  }>>;
3294
3305
  } & {
3295
3306
  title: z.ZodOptional<z.ZodString>;
@@ -4390,6 +4401,7 @@ export declare const mulmoScriptSchema: z.ZodObject<{
4390
4401
  outroPadding: number;
4391
4402
  bgmVolume: number;
4392
4403
  audioVolume: number;
4404
+ suppressSpeech: boolean;
4393
4405
  bgm?: {
4394
4406
  url: string;
4395
4407
  kind: "url";
@@ -4889,6 +4901,7 @@ export declare const mulmoScriptSchema: z.ZodObject<{
4889
4901
  } | undefined;
4890
4902
  bgmVolume?: number | undefined;
4891
4903
  audioVolume?: number | undefined;
4904
+ suppressSpeech?: boolean | undefined;
4892
4905
  } | undefined;
4893
4906
  movieParams?: {
4894
4907
  provider?: "openai" | "google" | "replicate" | undefined;
@@ -5418,6 +5431,7 @@ export declare const mulmoStudioSchema: z.ZodObject<{
5418
5431
  }>]>>;
5419
5432
  bgmVolume: z.ZodDefault<z.ZodNumber>;
5420
5433
  audioVolume: z.ZodDefault<z.ZodNumber>;
5434
+ suppressSpeech: z.ZodDefault<z.ZodBoolean>;
5421
5435
  }, "strict", z.ZodTypeAny, {
5422
5436
  padding: number;
5423
5437
  introPadding: number;
@@ -5425,6 +5439,7 @@ export declare const mulmoStudioSchema: z.ZodObject<{
5425
5439
  outroPadding: number;
5426
5440
  bgmVolume: number;
5427
5441
  audioVolume: number;
5442
+ suppressSpeech: boolean;
5428
5443
  bgm?: {
5429
5444
  url: string;
5430
5445
  kind: "url";
@@ -5458,6 +5473,7 @@ export declare const mulmoStudioSchema: z.ZodObject<{
5458
5473
  } | undefined;
5459
5474
  bgmVolume?: number | undefined;
5460
5475
  audioVolume?: number | undefined;
5476
+ suppressSpeech?: boolean | undefined;
5461
5477
  }>>;
5462
5478
  } & {
5463
5479
  title: z.ZodOptional<z.ZodString>;
@@ -6558,6 +6574,7 @@ export declare const mulmoStudioSchema: z.ZodObject<{
6558
6574
  outroPadding: number;
6559
6575
  bgmVolume: number;
6560
6576
  audioVolume: number;
6577
+ suppressSpeech: boolean;
6561
6578
  bgm?: {
6562
6579
  url: string;
6563
6580
  kind: "url";
@@ -7057,6 +7074,7 @@ export declare const mulmoStudioSchema: z.ZodObject<{
7057
7074
  } | undefined;
7058
7075
  bgmVolume?: number | undefined;
7059
7076
  audioVolume?: number | undefined;
7077
+ suppressSpeech?: boolean | undefined;
7060
7078
  } | undefined;
7061
7079
  movieParams?: {
7062
7080
  provider?: "openai" | "google" | "replicate" | undefined;
@@ -7145,6 +7163,7 @@ export declare const mulmoStudioSchema: z.ZodObject<{
7145
7163
  outroPadding: number;
7146
7164
  bgmVolume: number;
7147
7165
  audioVolume: number;
7166
+ suppressSpeech: boolean;
7148
7167
  bgm?: {
7149
7168
  url: string;
7150
7169
  kind: "url";
@@ -7655,6 +7674,7 @@ export declare const mulmoStudioSchema: z.ZodObject<{
7655
7674
  } | undefined;
7656
7675
  bgmVolume?: number | undefined;
7657
7676
  audioVolume?: number | undefined;
7677
+ suppressSpeech?: boolean | undefined;
7658
7678
  } | undefined;
7659
7679
  movieParams?: {
7660
7680
  provider?: "openai" | "google" | "replicate" | undefined;
@@ -8019,6 +8039,7 @@ export declare const mulmoScriptTemplateSchema: z.ZodObject<{
8019
8039
  }>]>>;
8020
8040
  bgmVolume: z.ZodDefault<z.ZodNumber>;
8021
8041
  audioVolume: z.ZodDefault<z.ZodNumber>;
8042
+ suppressSpeech: z.ZodDefault<z.ZodBoolean>;
8022
8043
  }, "strict", z.ZodTypeAny, {
8023
8044
  padding: number;
8024
8045
  introPadding: number;
@@ -8026,6 +8047,7 @@ export declare const mulmoScriptTemplateSchema: z.ZodObject<{
8026
8047
  outroPadding: number;
8027
8048
  bgmVolume: number;
8028
8049
  audioVolume: number;
8050
+ suppressSpeech: boolean;
8029
8051
  bgm?: {
8030
8052
  url: string;
8031
8053
  kind: "url";
@@ -8059,6 +8081,7 @@ export declare const mulmoScriptTemplateSchema: z.ZodObject<{
8059
8081
  } | undefined;
8060
8082
  bgmVolume?: number | undefined;
8061
8083
  audioVolume?: number | undefined;
8084
+ suppressSpeech?: boolean | undefined;
8062
8085
  }>>;
8063
8086
  }, "strip", z.ZodTypeAny, {
8064
8087
  audioParams: {
@@ -8068,6 +8091,7 @@ export declare const mulmoScriptTemplateSchema: z.ZodObject<{
8068
8091
  outroPadding: number;
8069
8092
  bgmVolume: number;
8070
8093
  audioVolume: number;
8094
+ suppressSpeech: boolean;
8071
8095
  bgm?: {
8072
8096
  url: string;
8073
8097
  kind: "url";
@@ -8193,6 +8217,7 @@ export declare const mulmoScriptTemplateSchema: z.ZodObject<{
8193
8217
  } | undefined;
8194
8218
  bgmVolume?: number | undefined;
8195
8219
  audioVolume?: number | undefined;
8220
+ suppressSpeech?: boolean | undefined;
8196
8221
  } | undefined;
8197
8222
  movieParams?: {
8198
8223
  provider?: "openai" | "google" | "replicate" | undefined;
@@ -8246,6 +8271,7 @@ export declare const mulmoScriptTemplateSchema: z.ZodObject<{
8246
8271
  outroPadding: number;
8247
8272
  bgmVolume: number;
8248
8273
  audioVolume: number;
8274
+ suppressSpeech: boolean;
8249
8275
  bgm?: {
8250
8276
  url: string;
8251
8277
  kind: "url";
@@ -8377,6 +8403,7 @@ export declare const mulmoScriptTemplateSchema: z.ZodObject<{
8377
8403
  } | undefined;
8378
8404
  bgmVolume?: number | undefined;
8379
8405
  audioVolume?: number | undefined;
8406
+ suppressSpeech?: boolean | undefined;
8380
8407
  } | undefined;
8381
8408
  movieParams?: {
8382
8409
  provider?: "openai" | "google" | "replicate" | undefined;
@@ -8732,6 +8759,7 @@ export declare const mulmoScriptTemplateFileSchema: z.ZodObject<{
8732
8759
  }>]>>;
8733
8760
  bgmVolume: z.ZodDefault<z.ZodNumber>;
8734
8761
  audioVolume: z.ZodDefault<z.ZodNumber>;
8762
+ suppressSpeech: z.ZodDefault<z.ZodBoolean>;
8735
8763
  }, "strict", z.ZodTypeAny, {
8736
8764
  padding: number;
8737
8765
  introPadding: number;
@@ -8739,6 +8767,7 @@ export declare const mulmoScriptTemplateFileSchema: z.ZodObject<{
8739
8767
  outroPadding: number;
8740
8768
  bgmVolume: number;
8741
8769
  audioVolume: number;
8770
+ suppressSpeech: boolean;
8742
8771
  bgm?: {
8743
8772
  url: string;
8744
8773
  kind: "url";
@@ -8772,6 +8801,7 @@ export declare const mulmoScriptTemplateFileSchema: z.ZodObject<{
8772
8801
  } | undefined;
8773
8802
  bgmVolume?: number | undefined;
8774
8803
  audioVolume?: number | undefined;
8804
+ suppressSpeech?: boolean | undefined;
8775
8805
  }>>;
8776
8806
  }, "strip", z.ZodTypeAny, {
8777
8807
  audioParams: {
@@ -8781,6 +8811,7 @@ export declare const mulmoScriptTemplateFileSchema: z.ZodObject<{
8781
8811
  outroPadding: number;
8782
8812
  bgmVolume: number;
8783
8813
  audioVolume: number;
8814
+ suppressSpeech: boolean;
8784
8815
  bgm?: {
8785
8816
  url: string;
8786
8817
  kind: "url";
@@ -8906,6 +8937,7 @@ export declare const mulmoScriptTemplateFileSchema: z.ZodObject<{
8906
8937
  } | undefined;
8907
8938
  bgmVolume?: number | undefined;
8908
8939
  audioVolume?: number | undefined;
8940
+ suppressSpeech?: boolean | undefined;
8909
8941
  } | undefined;
8910
8942
  movieParams?: {
8911
8943
  provider?: "openai" | "google" | "replicate" | undefined;
@@ -8962,6 +8994,7 @@ export declare const mulmoScriptTemplateFileSchema: z.ZodObject<{
8962
8994
  outroPadding: number;
8963
8995
  bgmVolume: number;
8964
8996
  audioVolume: number;
8997
+ suppressSpeech: boolean;
8965
8998
  bgm?: {
8966
8999
  url: string;
8967
9000
  kind: "url";
@@ -9094,6 +9127,7 @@ export declare const mulmoScriptTemplateFileSchema: z.ZodObject<{
9094
9127
  } | undefined;
9095
9128
  bgmVolume?: number | undefined;
9096
9129
  audioVolume?: number | undefined;
9130
+ suppressSpeech?: boolean | undefined;
9097
9131
  } | undefined;
9098
9132
  movieParams?: {
9099
9133
  provider?: "openai" | "google" | "replicate" | undefined;
@@ -185,6 +185,7 @@ export const audioParamsSchema = z
185
185
  bgm: mediaSourceSchema.optional(),
186
186
  bgmVolume: z.number().default(0.2).describe("Volume of the background music"),
187
187
  audioVolume: z.number().default(1.0).describe("Volume of the audio"),
188
+ suppressSpeech: z.boolean().default(false).describe("Suppress speech generation"),
188
189
  })
189
190
  .strict();
190
191
  export const htmlPromptParamsSchema = z
@@ -49,7 +49,6 @@ export type MulmoStudioContext = {
49
49
  fileDirs: FileDirs;
50
50
  studio: MulmoStudio;
51
51
  lang?: string;
52
- dryRun?: boolean;
53
52
  force: boolean;
54
53
  sessionState: MulmoSessionState;
55
54
  presentationStyle: MulmoPresentationStyle;
@@ -100,3 +99,27 @@ export type SessionProgressEvent = {
100
99
  inSession: boolean;
101
100
  };
102
101
  export type SessionProgressCallback = (change: SessionProgressEvent) => void;
102
+ export interface FileObject {
103
+ baseDirPath: string;
104
+ mulmoFilePath: string;
105
+ mulmoFileDirPath: string;
106
+ outDirPath: string;
107
+ imageDirPath: string;
108
+ audioDirPath: string;
109
+ isHttpPath: boolean;
110
+ fileOrUrl: string;
111
+ outputStudioFilePath: string;
112
+ outputMultilingualFilePath: string;
113
+ presentationStylePath: string | undefined;
114
+ fileName: string;
115
+ }
116
+ export type InitOptions = {
117
+ b?: string;
118
+ o?: string;
119
+ i?: string;
120
+ a?: string;
121
+ file?: string;
122
+ l?: string;
123
+ c?: string;
124
+ p?: string;
125
+ };
@@ -0,0 +1,414 @@
1
+ import type { MulmoScript, MulmoPresentationStyle, MulmoStudioMultiLingual } from "../types/type.js";
2
+ import { FileObject } from "../types/index.js";
3
+ export declare const fetchScript: (isHttpPath: boolean, mulmoFilePath: string, fileOrUrl: string) => Promise<MulmoScript | null>;
4
+ export declare const getMultiLingual: (multilingualFilePath: string, studioBeatsLength: number) => MulmoStudioMultiLingual;
5
+ 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<{
7
+ studio: {
8
+ beats: {
9
+ duration?: number | undefined;
10
+ hash?: string | undefined;
11
+ audioFile?: string | undefined;
12
+ imageFile?: string | undefined;
13
+ movieFile?: string | undefined;
14
+ captionFile?: string | undefined;
15
+ }[];
16
+ script: {
17
+ audioParams: {
18
+ padding: number;
19
+ introPadding: number;
20
+ closingPadding: number;
21
+ outroPadding: number;
22
+ bgmVolume: number;
23
+ audioVolume: number;
24
+ suppressSpeech: boolean;
25
+ bgm?: {
26
+ url: string;
27
+ kind: "url";
28
+ } | {
29
+ kind: "base64";
30
+ data: string;
31
+ } | {
32
+ text: string;
33
+ kind: "text";
34
+ } | {
35
+ path: string;
36
+ kind: "path";
37
+ } | undefined;
38
+ };
39
+ $mulmocast: {
40
+ version: "1.0";
41
+ credit?: "closing" | undefined;
42
+ };
43
+ canvasSize: {
44
+ width: number;
45
+ height: number;
46
+ };
47
+ speechParams: {
48
+ provider: "openai" | "nijivoice" | "google" | "elevenlabs";
49
+ speakers: Record<string, {
50
+ voiceId: string;
51
+ displayName?: Record<string, string> | undefined;
52
+ speechOptions?: {
53
+ speed?: number | undefined;
54
+ instruction?: string | undefined;
55
+ } | undefined;
56
+ provider?: "openai" | "nijivoice" | "google" | "elevenlabs" | undefined;
57
+ }>;
58
+ };
59
+ beats: {
60
+ text: string;
61
+ speaker: string;
62
+ duration?: number | undefined;
63
+ speechOptions?: {
64
+ speed?: number | undefined;
65
+ instruction?: string | undefined;
66
+ } | undefined;
67
+ image?: {
68
+ type: "markdown";
69
+ markdown: string | string[];
70
+ } | {
71
+ type: "web";
72
+ url: string;
73
+ } | {
74
+ type: "pdf";
75
+ source: {
76
+ url: string;
77
+ kind: "url";
78
+ } | {
79
+ kind: "base64";
80
+ data: string;
81
+ } | {
82
+ text: string;
83
+ kind: "text";
84
+ } | {
85
+ path: string;
86
+ kind: "path";
87
+ };
88
+ } | {
89
+ type: "image";
90
+ source: {
91
+ url: string;
92
+ kind: "url";
93
+ } | {
94
+ kind: "base64";
95
+ data: string;
96
+ } | {
97
+ text: string;
98
+ kind: "text";
99
+ } | {
100
+ path: string;
101
+ kind: "path";
102
+ };
103
+ } | {
104
+ type: "svg";
105
+ source: {
106
+ url: string;
107
+ kind: "url";
108
+ } | {
109
+ kind: "base64";
110
+ data: string;
111
+ } | {
112
+ text: string;
113
+ kind: "text";
114
+ } | {
115
+ path: string;
116
+ kind: "path";
117
+ };
118
+ } | {
119
+ type: "textSlide";
120
+ slide: {
121
+ title: string;
122
+ subtitle?: string | undefined;
123
+ bullets?: string[] | undefined;
124
+ };
125
+ } | {
126
+ type: "chart";
127
+ title: string;
128
+ chartData: Record<string, any>;
129
+ } | {
130
+ code: {
131
+ url: string;
132
+ kind: "url";
133
+ } | {
134
+ kind: "base64";
135
+ data: string;
136
+ } | {
137
+ text: string;
138
+ kind: "text";
139
+ } | {
140
+ path: string;
141
+ kind: "path";
142
+ };
143
+ type: "mermaid";
144
+ title: string;
145
+ appendix?: string[] | undefined;
146
+ } | {
147
+ type: "html_tailwind";
148
+ html: string | string[];
149
+ } | {
150
+ type: "beat";
151
+ id?: string | undefined;
152
+ } | {
153
+ type: "movie";
154
+ source: {
155
+ url: string;
156
+ kind: "url";
157
+ } | {
158
+ kind: "base64";
159
+ data: string;
160
+ } | {
161
+ text: string;
162
+ kind: "text";
163
+ } | {
164
+ path: string;
165
+ kind: "path";
166
+ };
167
+ mixAudio: number;
168
+ } | undefined;
169
+ id?: string | undefined;
170
+ audio?: {
171
+ type: "audio";
172
+ source: {
173
+ url: string;
174
+ kind: "url";
175
+ } | {
176
+ kind: "base64";
177
+ data: string;
178
+ } | {
179
+ text: string;
180
+ kind: "text";
181
+ } | {
182
+ path: string;
183
+ kind: "path";
184
+ };
185
+ } | {
186
+ type: "midi";
187
+ source: string;
188
+ } | undefined;
189
+ description?: string | undefined;
190
+ imageParams?: {
191
+ style?: string | undefined;
192
+ model?: string | undefined;
193
+ moderation?: string | undefined;
194
+ images?: Record<string, {
195
+ type: "image";
196
+ source: {
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
+ }> | undefined;
210
+ } | undefined;
211
+ audioParams?: {
212
+ padding?: number | undefined;
213
+ } | undefined;
214
+ movieParams?: {
215
+ fillOption: {
216
+ style: "aspectFit" | "aspectFill";
217
+ };
218
+ } | undefined;
219
+ htmlImageParams?: {
220
+ model?: string | undefined;
221
+ } | undefined;
222
+ textSlideParams?: {
223
+ cssStyles: string | string[];
224
+ } | undefined;
225
+ captionParams?: {
226
+ styles: string[];
227
+ lang?: string | undefined;
228
+ } | undefined;
229
+ imageNames?: string[] | undefined;
230
+ imagePrompt?: string | undefined;
231
+ moviePrompt?: string | undefined;
232
+ htmlPrompt?: {
233
+ prompt: string;
234
+ data?: any;
235
+ images?: Record<string, any> | undefined;
236
+ systemPrompt?: string | undefined;
237
+ } | undefined;
238
+ }[];
239
+ lang?: string | undefined;
240
+ title?: string | undefined;
241
+ description?: string | undefined;
242
+ imageParams?: {
243
+ provider: "openai" | "google";
244
+ style?: string | undefined;
245
+ model?: string | undefined;
246
+ moderation?: string | undefined;
247
+ images?: Record<string, {
248
+ type: "image";
249
+ source: {
250
+ url: string;
251
+ kind: "url";
252
+ } | {
253
+ kind: "base64";
254
+ data: string;
255
+ } | {
256
+ text: string;
257
+ kind: "text";
258
+ } | {
259
+ path: string;
260
+ kind: "path";
261
+ };
262
+ }> | undefined;
263
+ } | undefined;
264
+ movieParams?: {
265
+ provider?: "openai" | "google" | "replicate" | undefined;
266
+ model?: string | undefined;
267
+ fillOption?: {
268
+ style: "aspectFit" | "aspectFill";
269
+ } | undefined;
270
+ transition?: {
271
+ type: "fade" | "slideout_left";
272
+ duration: number;
273
+ } | undefined;
274
+ } | undefined;
275
+ htmlImageParams?: {
276
+ provider: "openai" | "anthropic";
277
+ model?: string | undefined;
278
+ } | undefined;
279
+ textSlideParams?: {
280
+ cssStyles: string | string[];
281
+ } | undefined;
282
+ captionParams?: {
283
+ styles: string[];
284
+ lang?: string | undefined;
285
+ } | undefined;
286
+ references?: {
287
+ type: "image" | "audio" | "article" | "paper" | "video";
288
+ url: string;
289
+ title?: string | undefined;
290
+ description?: string | undefined;
291
+ }[] | undefined;
292
+ imagePath?: string | undefined;
293
+ __test_invalid__?: boolean | undefined;
294
+ };
295
+ filename: string;
296
+ };
297
+ fileDirs: FileObject;
298
+ force: boolean;
299
+ lang: string | undefined;
300
+ sessionState: {
301
+ inSession: {
302
+ audio: boolean;
303
+ image: boolean;
304
+ video: boolean;
305
+ multiLingual: boolean;
306
+ caption: boolean;
307
+ pdf: boolean;
308
+ };
309
+ inBeatSession: {
310
+ audio: {};
311
+ image: {};
312
+ movie: {};
313
+ multiLingual: {};
314
+ caption: {};
315
+ };
316
+ };
317
+ presentationStyle: {
318
+ audioParams: {
319
+ padding: number;
320
+ introPadding: number;
321
+ closingPadding: number;
322
+ outroPadding: number;
323
+ bgmVolume: number;
324
+ audioVolume: number;
325
+ suppressSpeech: boolean;
326
+ bgm?: {
327
+ url: string;
328
+ kind: "url";
329
+ } | {
330
+ kind: "base64";
331
+ data: string;
332
+ } | {
333
+ text: string;
334
+ kind: "text";
335
+ } | {
336
+ path: string;
337
+ kind: "path";
338
+ } | undefined;
339
+ };
340
+ $mulmocast: {
341
+ version: "1.0";
342
+ credit?: "closing" | undefined;
343
+ };
344
+ canvasSize: {
345
+ width: number;
346
+ height: number;
347
+ };
348
+ speechParams: {
349
+ provider: "openai" | "nijivoice" | "google" | "elevenlabs";
350
+ speakers: Record<string, {
351
+ voiceId: string;
352
+ displayName?: Record<string, string> | undefined;
353
+ speechOptions?: {
354
+ speed?: number | undefined;
355
+ instruction?: string | undefined;
356
+ } | undefined;
357
+ provider?: "openai" | "nijivoice" | "google" | "elevenlabs" | undefined;
358
+ }>;
359
+ };
360
+ imageParams?: {
361
+ provider: "openai" | "google";
362
+ style?: string | undefined;
363
+ model?: string | undefined;
364
+ moderation?: string | undefined;
365
+ images?: Record<string, {
366
+ type: "image";
367
+ source: {
368
+ url: string;
369
+ kind: "url";
370
+ } | {
371
+ kind: "base64";
372
+ data: string;
373
+ } | {
374
+ text: string;
375
+ kind: "text";
376
+ } | {
377
+ path: string;
378
+ kind: "path";
379
+ };
380
+ }> | undefined;
381
+ } | undefined;
382
+ movieParams?: {
383
+ provider?: "openai" | "google" | "replicate" | undefined;
384
+ model?: string | undefined;
385
+ fillOption?: {
386
+ style: "aspectFit" | "aspectFill";
387
+ } | undefined;
388
+ transition?: {
389
+ type: "fade" | "slideout_left";
390
+ duration: number;
391
+ } | undefined;
392
+ } | undefined;
393
+ htmlImageParams?: {
394
+ provider: "openai" | "anthropic";
395
+ model?: string | undefined;
396
+ } | undefined;
397
+ textSlideParams?: {
398
+ cssStyles: string | string[];
399
+ } | undefined;
400
+ captionParams?: {
401
+ styles: string[];
402
+ lang?: string | undefined;
403
+ } | undefined;
404
+ };
405
+ multiLingual: {
406
+ multiLingualTexts: Record<string, {
407
+ text: string;
408
+ lang: string;
409
+ texts?: string[] | undefined;
410
+ ttsTexts?: string[] | undefined;
411
+ duration?: number | undefined;
412
+ }>;
413
+ }[];
414
+ } | null>;
@@ -0,0 +1,96 @@
1
+ import { GraphAILogger } from "graphai";
2
+ import fs from "fs";
3
+ import { readMulmoScriptFile, fetchMulmoScriptFile } from "./file.js";
4
+ import { createOrUpdateStudioData } from "./preprocess.js";
5
+ 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;
42
+ };
43
+ const initSessionState = () => {
44
+ return {
45
+ inSession: {
46
+ audio: false,
47
+ image: false,
48
+ video: false,
49
+ multiLingual: false,
50
+ caption: false,
51
+ pdf: false,
52
+ },
53
+ inBeatSession: {
54
+ audio: {},
55
+ image: {},
56
+ movie: {},
57
+ multiLingual: {},
58
+ caption: {},
59
+ },
60
+ };
61
+ };
62
+ const buildContext = (studio, files, presentationStyle, multiLingual, force, lang) => {
63
+ return {
64
+ studio,
65
+ fileDirs: files,
66
+ force: Boolean(force),
67
+ lang,
68
+ sessionState: initSessionState(),
69
+ presentationStyle: presentationStyle ?? studio.script,
70
+ multiLingual,
71
+ };
72
+ };
73
+ export const initializeContextFromFiles = async (files, raiseError, force, caption, lang) => {
74
+ const { fileName, isHttpPath, fileOrUrl, mulmoFilePath, outputStudioFilePath, presentationStylePath, outputMultilingualFilePath } = files;
75
+ // read mulmoScript, presentationStyle, currentStudio from files
76
+ const mulmoScript = await fetchScript(isHttpPath, mulmoFilePath, fileOrUrl);
77
+ if (!mulmoScript) {
78
+ return null;
79
+ }
80
+ const presentationStyle = getPresentationStyle(presentationStylePath);
81
+ // Create or update MulmoStudio file with MulmoScript
82
+ const currentStudio = readMulmoScriptFile(outputStudioFilePath);
83
+ try {
84
+ // validate mulmoStudioSchema. skip if __test_invalid__ is true
85
+ const studio = createOrUpdateStudioData(mulmoScript, currentStudio?.mulmoData, fileName, caption);
86
+ const multiLingual = getMultiLingual(outputMultilingualFilePath, studio.beats.length);
87
+ return buildContext(studio, files, presentationStyle, multiLingual, force, lang);
88
+ }
89
+ catch (error) {
90
+ GraphAILogger.info(`Error: invalid MulmoScript Schema: ${isHttpPath ? fileOrUrl : mulmoFilePath} \n ${error}`);
91
+ if (raiseError) {
92
+ throw error;
93
+ }
94
+ return null;
95
+ }
96
+ };
@@ -4,6 +4,8 @@ export type FfmpegContext = {
4
4
  inputCount: number;
5
5
  filterComplex: string[];
6
6
  };
7
+ export declare const setFfmpegPath: (ffmpegPath: string) => void;
8
+ export declare const setFfprobePath: (ffprobePath: string) => void;
7
9
  export declare const FfmpegContextInit: () => FfmpegContext;
8
10
  export declare const FfmpegContextAddInput: (context: FfmpegContext, input: string, inputOptions?: string[]) => number;
9
11
  export declare const FfmpegContextPushFormattedAudio: (context: FfmpegContext, sourceId: string, outputId: string, duration?: number | undefined) => void;
@@ -1,5 +1,11 @@
1
1
  import ffmpeg from "fluent-ffmpeg";
2
2
  import { GraphAILogger } from "graphai";
3
+ export const setFfmpegPath = (ffmpegPath) => {
4
+ ffmpeg.setFfmpegPath(ffmpegPath);
5
+ };
6
+ export const setFfprobePath = (ffprobePath) => {
7
+ ffmpeg.setFfprobePath(ffprobePath);
8
+ };
3
9
  export const FfmpegContextInit = () => {
4
10
  return {
5
11
  command: ffmpeg(),
@@ -1,5 +1,5 @@
1
1
  import { MulmoStudio, MulmoScript } from "../types/index.js";
2
- export declare const createOrUpdateStudioData: (_mulmoScript: MulmoScript, currentStudio: MulmoStudio | undefined, fileName: string) => {
2
+ export declare const createOrUpdateStudioData: (_mulmoScript: MulmoScript, currentStudio: MulmoStudio | undefined, fileName: string, videoCaption?: string) => {
3
3
  beats: {
4
4
  duration?: number | undefined;
5
5
  hash?: string | undefined;
@@ -16,6 +16,7 @@ export declare const createOrUpdateStudioData: (_mulmoScript: MulmoScript, curre
16
16
  outroPadding: number;
17
17
  bgmVolume: number;
18
18
  audioVolume: number;
19
+ suppressSpeech: boolean;
19
20
  bgm?: {
20
21
  url: string;
21
22
  kind: "url";
@@ -1,5 +1,5 @@
1
1
  import { GraphAILogger } from "graphai";
2
- import { mulmoScriptSchema, mulmoStudioSchema } from "../types/index.js";
2
+ import { mulmoScriptSchema, mulmoStudioSchema, mulmoCaptionParamsSchema } from "../types/index.js";
3
3
  const rebuildStudio = (currentStudio, mulmoScript, fileName) => {
4
4
  const isTest = process.env.NODE_ENV === "test";
5
5
  const parsed = isTest && currentStudio ? { data: mulmoStudioSchema.parse(currentStudio), success: true, error: null } : mulmoStudioSchema.safeParse(currentStudio);
@@ -36,7 +36,7 @@ const mulmoCredit = (speaker) => {
36
36
  },
37
37
  };
38
38
  };
39
- export const createOrUpdateStudioData = (_mulmoScript, currentStudio, fileName) => {
39
+ export const createOrUpdateStudioData = (_mulmoScript, currentStudio, fileName, videoCaption) => {
40
40
  const mulmoScript = _mulmoScript.__test_invalid__ ? _mulmoScript : mulmoScriptSchema.parse(_mulmoScript); // validate and insert default value
41
41
  const studio = rebuildStudio(currentStudio, mulmoScript, fileName);
42
42
  // TODO: Move this code out of this function later
@@ -46,5 +46,11 @@ export const createOrUpdateStudioData = (_mulmoScript, currentStudio, fileName)
46
46
  }
47
47
  studio.script = mulmoScriptSchema.parse(mulmoScript); // update the script
48
48
  studio.beats = studio.script.beats.map((_, index) => studio.beats[index] ?? {});
49
+ if (videoCaption) {
50
+ studio.script.captionParams = mulmoCaptionParamsSchema.parse({
51
+ ...(studio.script.captionParams ?? {}),
52
+ lang: videoCaption,
53
+ });
54
+ }
49
55
  return studio;
50
56
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mulmocast",
3
- "version": "0.0.26",
3
+ "version": "0.0.28",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
@@ -78,12 +78,12 @@
78
78
  "google-auth-library": "^9.15.1",
79
79
  "graphai": "^2.0.9",
80
80
  "inquirer": "^12.6.3",
81
- "marked": "^15.0.12",
81
+ "marked": "^16.0.0",
82
82
  "ora": "^8.2.0",
83
- "puppeteer": "^24.11.0",
83
+ "puppeteer": "^24.11.1",
84
84
  "replicate": "^1.0.1",
85
85
  "yaml": "^2.8.0",
86
- "yargs": "^17.7.2",
86
+ "yargs": "^18.0.0",
87
87
  "zod": "^3.25.67",
88
88
  "zod-to-json-schema": "^3.24.6"
89
89
  },