mulmocast 2.4.5 → 2.4.7
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/assets/html/caption.html +1 -1
- package/lib/actions/captions.js +1 -0
- package/lib/types/schema.d.ts +9 -0
- package/lib/types/schema.js +1 -0
- package/lib/utils/context.d.ts +5 -0
- package/lib/utils/image_plugins/html_tailwind.js +17 -4
- package/package.json +1 -1
- package/scripts/test/cinematic_showcase.json +6 -21
package/assets/html/caption.html
CHANGED
package/lib/actions/captions.js
CHANGED
|
@@ -89,6 +89,7 @@ const generateBeatCaptions = async (beat, context, index) => {
|
|
|
89
89
|
width: `${canvasSize.width}`,
|
|
90
90
|
height: `${canvasSize.height}`,
|
|
91
91
|
styles: (mergedCaptionParams.styles ?? []).join(";\n"),
|
|
92
|
+
bottomOffset: `${mergedCaptionParams.bottomOffset ?? 0}`,
|
|
92
93
|
});
|
|
93
94
|
await renderHTMLToImage(htmlData, imagePath, canvasSize.width, canvasSize.height, false, true);
|
|
94
95
|
return {
|
package/lib/types/schema.d.ts
CHANGED
|
@@ -327,6 +327,7 @@ export declare const mulmoCaptionParamsSchema: z.ZodObject<{
|
|
|
327
327
|
type: z.ZodLiteral<"delimiters">;
|
|
328
328
|
delimiters: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
329
329
|
}, z.core.$strip>], "type">>;
|
|
330
|
+
bottomOffset: z.ZodOptional<z.ZodNumber>;
|
|
330
331
|
}, z.core.$strict>;
|
|
331
332
|
export declare const mulmoChartMediaSchema: z.ZodObject<{
|
|
332
333
|
type: z.ZodLiteral<"chart">;
|
|
@@ -6288,6 +6289,7 @@ export declare const mulmoBeatSchema: z.ZodObject<{
|
|
|
6288
6289
|
type: z.ZodLiteral<"delimiters">;
|
|
6289
6290
|
delimiters: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
6290
6291
|
}, z.core.$strip>], "type">>;
|
|
6292
|
+
bottomOffset: z.ZodOptional<z.ZodNumber>;
|
|
6291
6293
|
}, z.core.$strict>>;
|
|
6292
6294
|
imageNames: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
6293
6295
|
imagePrompt: z.ZodOptional<z.ZodString>;
|
|
@@ -6747,6 +6749,7 @@ export declare const mulmoPresentationStyleSchema: z.ZodObject<{
|
|
|
6747
6749
|
type: z.ZodLiteral<"delimiters">;
|
|
6748
6750
|
delimiters: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
6749
6751
|
}, z.core.$strip>], "type">>;
|
|
6752
|
+
bottomOffset: z.ZodOptional<z.ZodNumber>;
|
|
6750
6753
|
}, z.core.$strict>>;
|
|
6751
6754
|
audioParams: z.ZodDefault<z.ZodObject<{
|
|
6752
6755
|
padding: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
@@ -7202,6 +7205,7 @@ export declare const mulmoScriptSchema: z.ZodObject<{
|
|
|
7202
7205
|
type: z.ZodLiteral<"delimiters">;
|
|
7203
7206
|
delimiters: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
7204
7207
|
}, z.core.$strip>], "type">>;
|
|
7208
|
+
bottomOffset: z.ZodOptional<z.ZodNumber>;
|
|
7205
7209
|
}, z.core.$strict>>;
|
|
7206
7210
|
audioParams: z.ZodDefault<z.ZodObject<{
|
|
7207
7211
|
padding: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
@@ -10083,6 +10087,7 @@ export declare const mulmoScriptSchema: z.ZodObject<{
|
|
|
10083
10087
|
type: z.ZodLiteral<"delimiters">;
|
|
10084
10088
|
delimiters: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
10085
10089
|
}, z.core.$strip>], "type">>;
|
|
10090
|
+
bottomOffset: z.ZodOptional<z.ZodNumber>;
|
|
10086
10091
|
}, z.core.$strict>>;
|
|
10087
10092
|
imageNames: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
10088
10093
|
imagePrompt: z.ZodOptional<z.ZodString>;
|
|
@@ -10617,6 +10622,7 @@ export declare const mulmoStudioSchema: z.ZodObject<{
|
|
|
10617
10622
|
type: z.ZodLiteral<"delimiters">;
|
|
10618
10623
|
delimiters: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
10619
10624
|
}, z.core.$strip>], "type">>;
|
|
10625
|
+
bottomOffset: z.ZodOptional<z.ZodNumber>;
|
|
10620
10626
|
}, z.core.$strict>>;
|
|
10621
10627
|
audioParams: z.ZodDefault<z.ZodObject<{
|
|
10622
10628
|
padding: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
@@ -13498,6 +13504,7 @@ export declare const mulmoStudioSchema: z.ZodObject<{
|
|
|
13498
13504
|
type: z.ZodLiteral<"delimiters">;
|
|
13499
13505
|
delimiters: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
13500
13506
|
}, z.core.$strip>], "type">>;
|
|
13507
|
+
bottomOffset: z.ZodOptional<z.ZodNumber>;
|
|
13501
13508
|
}, z.core.$strict>>;
|
|
13502
13509
|
imageNames: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
13503
13510
|
imagePrompt: z.ZodOptional<z.ZodString>;
|
|
@@ -13968,6 +13975,7 @@ export declare const mulmoPromptTemplateSchema: z.ZodObject<{
|
|
|
13968
13975
|
type: z.ZodLiteral<"delimiters">;
|
|
13969
13976
|
delimiters: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
13970
13977
|
}, z.core.$strip>], "type">>;
|
|
13978
|
+
bottomOffset: z.ZodOptional<z.ZodNumber>;
|
|
13971
13979
|
}, z.core.$strict>>;
|
|
13972
13980
|
audioParams: z.ZodDefault<z.ZodObject<{
|
|
13973
13981
|
padding: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
@@ -14417,6 +14425,7 @@ export declare const mulmoPromptTemplateFileSchema: z.ZodObject<{
|
|
|
14417
14425
|
type: z.ZodLiteral<"delimiters">;
|
|
14418
14426
|
delimiters: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
14419
14427
|
}, z.core.$strip>], "type">>;
|
|
14428
|
+
bottomOffset: z.ZodOptional<z.ZodNumber>;
|
|
14420
14429
|
}, z.core.$strict>>;
|
|
14421
14430
|
audioParams: z.ZodDefault<z.ZodObject<{
|
|
14422
14431
|
padding: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
package/lib/types/schema.js
CHANGED
|
@@ -174,6 +174,7 @@ export const mulmoCaptionParamsSchema = z
|
|
|
174
174
|
styles: z.array(z.string()).optional(), // css styles
|
|
175
175
|
captionSplit: captionSplitSchema.optional(), // how to determine caption timing
|
|
176
176
|
textSplit: textSplitSchema.optional(), // how to split text into segments (default: none)
|
|
177
|
+
bottomOffset: z.number().min(0).max(100).optional(), // bottom offset in percentage (e.g., 20 = 20% from bottom)
|
|
177
178
|
})
|
|
178
179
|
.strict();
|
|
179
180
|
export const mulmoChartMediaSchema = z
|
package/lib/utils/context.d.ts
CHANGED
|
@@ -1960,6 +1960,7 @@ export declare const createStudioData: (_mulmoScript: MulmoScript, fileName: str
|
|
|
1960
1960
|
type: "delimiters";
|
|
1961
1961
|
delimiters?: string[] | undefined;
|
|
1962
1962
|
} | undefined;
|
|
1963
|
+
bottomOffset?: number | undefined;
|
|
1963
1964
|
} | undefined;
|
|
1964
1965
|
imageNames?: string[] | undefined;
|
|
1965
1966
|
imagePrompt?: string | undefined;
|
|
@@ -2050,6 +2051,7 @@ export declare const createStudioData: (_mulmoScript: MulmoScript, fileName: str
|
|
|
2050
2051
|
type: "delimiters";
|
|
2051
2052
|
delimiters?: string[] | undefined;
|
|
2052
2053
|
} | undefined;
|
|
2054
|
+
bottomOffset?: number | undefined;
|
|
2053
2055
|
} | undefined;
|
|
2054
2056
|
title?: string | undefined;
|
|
2055
2057
|
description?: string | undefined;
|
|
@@ -4052,6 +4054,7 @@ export declare const initializeContextFromFiles: (files: FileObject, raiseError:
|
|
|
4052
4054
|
type: "delimiters";
|
|
4053
4055
|
delimiters?: string[] | undefined;
|
|
4054
4056
|
} | undefined;
|
|
4057
|
+
bottomOffset?: number | undefined;
|
|
4055
4058
|
} | undefined;
|
|
4056
4059
|
imageNames?: string[] | undefined;
|
|
4057
4060
|
imagePrompt?: string | undefined;
|
|
@@ -4142,6 +4145,7 @@ export declare const initializeContextFromFiles: (files: FileObject, raiseError:
|
|
|
4142
4145
|
type: "delimiters";
|
|
4143
4146
|
delimiters?: string[] | undefined;
|
|
4144
4147
|
} | undefined;
|
|
4148
|
+
bottomOffset?: number | undefined;
|
|
4145
4149
|
} | undefined;
|
|
4146
4150
|
title?: string | undefined;
|
|
4147
4151
|
description?: string | undefined;
|
|
@@ -4534,6 +4538,7 @@ export declare const initializeContextFromFiles: (files: FileObject, raiseError:
|
|
|
4534
4538
|
type: "delimiters";
|
|
4535
4539
|
delimiters?: string[] | undefined;
|
|
4536
4540
|
} | undefined;
|
|
4541
|
+
bottomOffset?: number | undefined;
|
|
4537
4542
|
} | undefined;
|
|
4538
4543
|
};
|
|
4539
4544
|
sessionState: {
|
|
@@ -1,10 +1,21 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
|
+
import nodePath from "node:path";
|
|
2
3
|
import { MulmoBeatMethods } from "../../methods/mulmo_beat.js";
|
|
3
4
|
import { getHTMLFile } from "../file.js";
|
|
4
5
|
import { renderHTMLToImage, interpolate, renderHTMLToFrames } from "../html_render.js";
|
|
5
6
|
import { framesToVideo } from "../ffmpeg_utils.js";
|
|
6
7
|
import { parrotingImagePath } from "./utils.js";
|
|
7
8
|
export const imageType = "html_tailwind";
|
|
9
|
+
/**
|
|
10
|
+
* Resolve relative paths in src attributes to file:// absolute paths.
|
|
11
|
+
* Paths starting with http://, https://, file://, data:, or / are left unchanged.
|
|
12
|
+
*/
|
|
13
|
+
const resolveRelativeImagePaths = (html, baseDirPath) => {
|
|
14
|
+
return html.replace(/(\bsrc\s*=\s*)(["'])((?!https?:\/\/|file:\/\/|data:|\/)[^"']+)\2/gi, (_, prefix, quote, relativePath) => {
|
|
15
|
+
const absolutePath = nodePath.resolve(baseDirPath, relativePath);
|
|
16
|
+
return `${prefix}${quote}file://${absolutePath}${quote}`;
|
|
17
|
+
});
|
|
18
|
+
};
|
|
8
19
|
const DEFAULT_ANIMATION_FPS = 30;
|
|
9
20
|
/** Join html field into a single string (handles both string and string[]) */
|
|
10
21
|
const joinHtml = (html) => {
|
|
@@ -28,7 +39,7 @@ const getAnimationConfig = (params) => {
|
|
|
28
39
|
return { fps: DEFAULT_ANIMATION_FPS };
|
|
29
40
|
};
|
|
30
41
|
const processHtmlTailwindAnimated = async (params) => {
|
|
31
|
-
const { beat, imagePath, canvasSize } = params;
|
|
42
|
+
const { beat, imagePath, canvasSize, context } = params;
|
|
32
43
|
if (!beat.image || beat.image.type !== imageType)
|
|
33
44
|
return;
|
|
34
45
|
const animConfig = getAnimationConfig(params);
|
|
@@ -46,13 +57,14 @@ const processHtmlTailwindAnimated = async (params) => {
|
|
|
46
57
|
const html = joinHtml(beat.image.html);
|
|
47
58
|
const template = getHTMLFile("tailwind_animated");
|
|
48
59
|
const script = "script" in beat.image ? beat.image.script : undefined;
|
|
49
|
-
const
|
|
60
|
+
const rawHtmlData = interpolate(template, {
|
|
50
61
|
html_body: html,
|
|
51
62
|
user_script: buildUserScript(script),
|
|
52
63
|
totalFrames: String(totalFrames),
|
|
53
64
|
fps: String(fps),
|
|
54
65
|
custom_style: "",
|
|
55
66
|
});
|
|
67
|
+
const htmlData = resolveRelativeImagePaths(rawHtmlData, context.fileDirs.mulmoFileDirPath);
|
|
56
68
|
// imagePath is set to the .mp4 path by imagePluginAgent for animated beats
|
|
57
69
|
const videoPath = imagePath;
|
|
58
70
|
// Create frames directory next to the video file
|
|
@@ -68,16 +80,17 @@ const processHtmlTailwindAnimated = async (params) => {
|
|
|
68
80
|
return videoPath;
|
|
69
81
|
};
|
|
70
82
|
const processHtmlTailwindStatic = async (params) => {
|
|
71
|
-
const { beat, imagePath, canvasSize } = params;
|
|
83
|
+
const { beat, imagePath, canvasSize, context } = params;
|
|
72
84
|
if (!beat.image || beat.image.type !== imageType)
|
|
73
85
|
return;
|
|
74
86
|
const html = joinHtml(beat.image.html);
|
|
75
87
|
const template = getHTMLFile("tailwind");
|
|
76
88
|
const script = "script" in beat.image ? beat.image.script : undefined;
|
|
77
|
-
const
|
|
89
|
+
const rawHtmlData = interpolate(template, {
|
|
78
90
|
html_body: html,
|
|
79
91
|
user_script: buildUserScript(script),
|
|
80
92
|
});
|
|
93
|
+
const htmlData = resolveRelativeImagePaths(rawHtmlData, context.fileDirs.mulmoFileDirPath);
|
|
81
94
|
await renderHTMLToImage(htmlData, imagePath, canvasSize.width, canvasSize.height);
|
|
82
95
|
return imagePath;
|
|
83
96
|
};
|
package/package.json
CHANGED
|
@@ -339,10 +339,7 @@
|
|
|
339
339
|
" </div>",
|
|
340
340
|
"</div>"
|
|
341
341
|
],
|
|
342
|
-
"script": [
|
|
343
|
-
"const animation = new MulmoAnimation();",
|
|
344
|
-
"animation.animate('#t', { opacity: [0, 1] }, { start: 0.5, end: 1.5 });"
|
|
345
|
-
],
|
|
342
|
+
"script": ["const animation = new MulmoAnimation();", "animation.animate('#t', { opacity: [0, 1] }, { start: 0.5, end: 1.5 });"],
|
|
346
343
|
"animation": true
|
|
347
344
|
}
|
|
348
345
|
},
|
|
@@ -490,10 +487,7 @@
|
|
|
490
487
|
" <div id='t' class='text-7xl font-bold' style='font-family:\"Courier New\",Monaco,monospace;color:#00ff00;opacity:0'>THE MATRIX</div>",
|
|
491
488
|
"</div>"
|
|
492
489
|
],
|
|
493
|
-
"script": [
|
|
494
|
-
"const animation = new MulmoAnimation();",
|
|
495
|
-
"animation.animate('#t', { opacity: [0, 1] }, { start: 0.3, end: 1.0 });"
|
|
496
|
-
],
|
|
490
|
+
"script": ["const animation = new MulmoAnimation();", "animation.animate('#t', { opacity: [0, 1] }, { start: 0.3, end: 1.0 });"],
|
|
497
491
|
"animation": true
|
|
498
492
|
}
|
|
499
493
|
},
|
|
@@ -565,10 +559,7 @@
|
|
|
565
559
|
" <div id='t' class='text-7xl font-bold tracking-wide' style='font-family:Georgia,serif;color:#2c3e50;opacity:0'>DOCUMENTARY</div>",
|
|
566
560
|
"</div>"
|
|
567
561
|
],
|
|
568
|
-
"script": [
|
|
569
|
-
"const animation = new MulmoAnimation();",
|
|
570
|
-
"animation.animate('#t', { opacity: [0, 1] }, { start: 0.5, end: 1.5 });"
|
|
571
|
-
],
|
|
562
|
+
"script": ["const animation = new MulmoAnimation();", "animation.animate('#t', { opacity: [0, 1] }, { start: 0.5, end: 1.5 });"],
|
|
572
563
|
"animation": true
|
|
573
564
|
}
|
|
574
565
|
},
|
|
@@ -716,10 +707,7 @@
|
|
|
716
707
|
" </div>",
|
|
717
708
|
"</div>"
|
|
718
709
|
],
|
|
719
|
-
"script": [
|
|
720
|
-
"const animation = new MulmoAnimation();",
|
|
721
|
-
"animation.animate('#t', { opacity: [0, 1] }, { start: 1.0, end: 2.5 });"
|
|
722
|
-
],
|
|
710
|
+
"script": ["const animation = new MulmoAnimation();", "animation.animate('#t', { opacity: [0, 1] }, { start: 1.0, end: 2.5 });"],
|
|
723
711
|
"animation": true
|
|
724
712
|
}
|
|
725
713
|
},
|
|
@@ -913,10 +901,7 @@
|
|
|
913
901
|
" </div>",
|
|
914
902
|
"</div>"
|
|
915
903
|
],
|
|
916
|
-
"script": [
|
|
917
|
-
"const animation = new MulmoAnimation();",
|
|
918
|
-
"animation.animate('#title', { opacity: [0, 1] }, { start: 0.5, end: 1.5 });"
|
|
919
|
-
],
|
|
904
|
+
"script": ["const animation = new MulmoAnimation();", "animation.animate('#title', { opacity: [0, 1] }, { start: 0.5, end: 1.5 });"],
|
|
920
905
|
"animation": true
|
|
921
906
|
}
|
|
922
907
|
},
|
|
@@ -1368,4 +1353,4 @@
|
|
|
1368
1353
|
}
|
|
1369
1354
|
}
|
|
1370
1355
|
]
|
|
1371
|
-
}
|
|
1356
|
+
}
|