@glissade/cli 0.8.1-pre.1 → 0.9.0-pre.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.
- package/dist/cli.js +2 -0
- package/dist/index.d.ts +3 -1
- package/dist/machines.js +1 -1
- package/dist/render.js +26 -16
- package/package.json +10 -10
package/dist/cli.js
CHANGED
|
@@ -61,6 +61,7 @@ render options:
|
|
|
61
61
|
--music <m> auto (default): mix a sibling *.music.timing.json bed, ducked under narration | off
|
|
62
62
|
--sfx <m> auto (default): mix effect hits from a sibling *.sfx.timing.json | off
|
|
63
63
|
--chapters <m> vtt: also write WebVTT chapters from cue markers (cues.json is always written when cues exist)
|
|
64
|
+
--strict fail on an unregistered font family or an uncovered glyph (§3.6; default: warn)
|
|
64
65
|
|
|
65
66
|
dev options:
|
|
66
67
|
--record add a Record button; writes .trace.json sidecars next to the module
|
|
@@ -191,6 +192,7 @@ async function main() {
|
|
|
191
192
|
...flags.has("trace") ? { trace: flags.get("trace") } : {},
|
|
192
193
|
...flags.has("state") ? { state: flags.get("state") } : {},
|
|
193
194
|
...flags.has("force") ? { force: true } : {},
|
|
195
|
+
...flags.has("strict") ? { strictFonts: true } : {},
|
|
194
196
|
captions: parseCaptionsModeOrFail(flags.get("captions")),
|
|
195
197
|
narration: flags.get("narration") === "off" ? "off" : "auto",
|
|
196
198
|
music: flags.get("music") === "off" ? "off" : "auto",
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Scene, SceneModule, VideoFrameSource } from "@glissade/scene";
|
|
2
1
|
import { AudioClip, Key, Timeline } from "@glissade/core";
|
|
2
|
+
import { Scene, SceneModule, VideoFrameSource } from "@glissade/scene";
|
|
3
3
|
import { Image } from "@napi-rs/canvas";
|
|
4
4
|
|
|
5
5
|
//#region src/render.d.ts
|
|
@@ -32,6 +32,8 @@ interface RenderOptions {
|
|
|
32
32
|
sfx?: 'auto' | 'off';
|
|
33
33
|
/** also write WebVTT chapters from cue markers ('vtt'); cues.json is always written when cues exist. */
|
|
34
34
|
chapters?: 'vtt' | 'off';
|
|
35
|
+
/** --strict: font validation throws on an unregistered family / missing glyph (§3.6). Default dev-warn. */
|
|
36
|
+
strictFonts?: boolean;
|
|
35
37
|
onProgress?: (frame: number, total: number) => void;
|
|
36
38
|
}
|
|
37
39
|
declare class SceneModuleError extends Error {
|
package/dist/machines.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime.js";
|
|
2
2
|
import { readFileSync } from "node:fs";
|
|
3
|
-
import "@glissade/scene";
|
|
4
3
|
import { compileTimeline, timeline } from "@glissade/core";
|
|
4
|
+
import "@glissade/scene";
|
|
5
5
|
import { bakeTrace, createMachine } from "@glissade/interact";
|
|
6
6
|
//#region src/machines.ts
|
|
7
7
|
/**
|
package/dist/render.js
CHANGED
|
@@ -3,8 +3,10 @@ import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
|
3
3
|
import { tmpdir } from "node:os";
|
|
4
4
|
import { dirname, isAbsolute, join, resolve } from "node:path";
|
|
5
5
|
import { pathToFileURL } from "node:url";
|
|
6
|
+
import { readFile } from "node:fs/promises";
|
|
6
7
|
import { createJiti } from "jiti";
|
|
7
|
-
import {
|
|
8
|
+
import { buildFontRegistry } from "@glissade/core";
|
|
9
|
+
import { evaluate, validateSceneFonts, withDeterminismGuards } from "@glissade/scene";
|
|
8
10
|
import { SkiaBackend } from "@glissade/backend-skia";
|
|
9
11
|
//#region src/render.ts
|
|
10
12
|
/**
|
|
@@ -81,22 +83,30 @@ async function render(opts) {
|
|
|
81
83
|
await loadYogaLayoutEngine();
|
|
82
84
|
}
|
|
83
85
|
const videoSources = [];
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
await source.warm(0, source.duration);
|
|
97
|
-
backend.setVideoAsset(assetId, source);
|
|
98
|
-
videoSources.push(source);
|
|
86
|
+
const { resolveAssetPath: resolveAsset } = await import("./audioMix.js").then((n) => n.r);
|
|
87
|
+
const fontRegistry = buildFontRegistry(doc.assets);
|
|
88
|
+
if (fontRegistry.faces().length > 0) {
|
|
89
|
+
const { GlobalFonts } = await import("@napi-rs/canvas");
|
|
90
|
+
for (const face of fontRegistry.faces()) GlobalFonts.registerFromPath(resolveAsset(face.url, opts.modulePath), face.family);
|
|
91
|
+
}
|
|
92
|
+
await validateSceneFonts(scene, doc, async (url) => {
|
|
93
|
+
try {
|
|
94
|
+
const buf = await readFile(resolveAsset(url, opts.modulePath));
|
|
95
|
+
return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
|
|
96
|
+
} catch {
|
|
97
|
+
return;
|
|
99
98
|
}
|
|
99
|
+
}, { mode: opts.strictFonts ? "strict" : "dev" });
|
|
100
|
+
for (const [assetId, ref] of Object.entries(doc.assets ?? {})) if (ref.kind === "font") {} else if (ref.kind === "image") {
|
|
101
|
+
const { loadImage } = await import("@napi-rs/canvas");
|
|
102
|
+
backend.setImageAsset(assetId, await loadImage(resolveAsset(ref.url, opts.modulePath)));
|
|
103
|
+
} else if (ref.kind === "video") {
|
|
104
|
+
if (!ffmpegAvailable()) throw new Error(`video asset '${assetId}' needs FFmpeg on PATH for frame extraction (§5.4)`);
|
|
105
|
+
const { FfmpegVideoFrameSource } = await import("./videoSource.js").then((n) => n.i);
|
|
106
|
+
const source = new FfmpegVideoFrameSource(resolveAsset(ref.url, opts.modulePath));
|
|
107
|
+
await source.warm(0, source.duration);
|
|
108
|
+
backend.setVideoAsset(assetId, source);
|
|
109
|
+
videoSources.push(source);
|
|
100
110
|
}
|
|
101
111
|
for (let f = firstFrame; f <= lastFrame; f++) {
|
|
102
112
|
backend.render(withDeterminismGuards("throw", () => evaluate(scene, doc, f / fps)));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@glissade/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0-pre.0",
|
|
4
4
|
"description": "glissade CLI: headless rendering via backend-skia (+ FFmpeg mux).",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -20,15 +20,15 @@
|
|
|
20
20
|
"@napi-rs/canvas": "^0.1.65",
|
|
21
21
|
"esbuild": "^0.28.0",
|
|
22
22
|
"jiti": "^2.4.2",
|
|
23
|
-
"@glissade/backend-skia": "0.
|
|
24
|
-
"@glissade/core": "0.
|
|
25
|
-
"@glissade/interact": "0.
|
|
26
|
-
"@glissade/lottie": "0.
|
|
27
|
-
"@glissade/svg": "0.
|
|
28
|
-
"@glissade/narrate": "0.
|
|
29
|
-
"@glissade/player": "0.
|
|
30
|
-
"@glissade/scene": "0.
|
|
31
|
-
"@glissade/sfx": "0.
|
|
23
|
+
"@glissade/backend-skia": "0.9.0-pre.0",
|
|
24
|
+
"@glissade/core": "0.9.0-pre.0",
|
|
25
|
+
"@glissade/interact": "0.9.0-pre.0",
|
|
26
|
+
"@glissade/lottie": "0.9.0-pre.0",
|
|
27
|
+
"@glissade/svg": "0.9.0-pre.0",
|
|
28
|
+
"@glissade/narrate": "0.9.0-pre.0",
|
|
29
|
+
"@glissade/player": "0.9.0-pre.0",
|
|
30
|
+
"@glissade/scene": "0.9.0-pre.0",
|
|
31
|
+
"@glissade/sfx": "0.9.0-pre.0"
|
|
32
32
|
},
|
|
33
33
|
"repository": {
|
|
34
34
|
"type": "git",
|