@scenar/cli 0.9.1 → 0.11.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/example-bundle/assets/index-DxmqjG-8.js +388 -0
- package/example-bundle/assets/style-B2sxnVVZ.css +1 -0
- package/example-bundle/embed.js +1 -1
- package/example-bundle/index.html +2 -2
- package/example-bundle/logo.png +0 -0
- package/example-bundle/pack-manifest.json +33 -9
- package/example-bundle/soundtrack/music.mp3 +0 -0
- package/example-bundle/soundtrack/sfx/click.mp3 +0 -0
- package/example-bundle/soundtrack/sfx/keystroke.mp3 +0 -0
- package/package.json +4 -4
- package/src/__tests__/collect-pack-shots.test.ts +27 -1
- package/src/__tests__/elevenlabs-provider.test.ts +187 -0
- package/src/__tests__/embed-snippet.test.ts +5 -0
- package/src/__tests__/find-authored-soundtrack.test.ts +54 -0
- package/src/__tests__/find-authored-title-cards.test.ts +65 -0
- package/src/__tests__/find-authored-viewport.test.ts +58 -0
- package/src/__tests__/load-bundle.test.ts +67 -0
- package/src/__tests__/narrate-command.test.ts +65 -1
- package/src/__tests__/narration-cache.test.ts +134 -0
- package/src/__tests__/pack-bundle-contract.test.ts +2 -0
- package/src/__tests__/pack-generate-embed-entry.test.ts +99 -16
- package/src/__tests__/presenter-command.test.ts +366 -0
- package/src/__tests__/render-command.test.ts +11 -0
- package/src/__tests__/render-generate-entry.test.ts +102 -0
- package/src/__tests__/resolve-pack-viewport.test.ts +46 -0
- package/src/__tests__/resolve-provider.test.ts +32 -3
- package/src/__tests__/scenario-validator.test.ts +174 -0
- package/src/__tests__/stage-assets.test.ts +269 -0
- package/src/commands/narrate.js +1 -1
- package/src/commands/narrate.js.map +1 -1
- package/src/commands/narrate.ts +1 -1
- package/src/commands/pack.d.ts.map +1 -1
- package/src/commands/pack.js +23 -4
- package/src/commands/pack.js.map +1 -1
- package/src/commands/pack.ts +26 -5
- package/src/commands/presenter.d.ts +3 -0
- package/src/commands/presenter.d.ts.map +1 -0
- package/src/commands/presenter.js +89 -0
- package/src/commands/presenter.js.map +1 -0
- package/src/commands/presenter.ts +107 -0
- package/src/commands/render.d.ts.map +1 -1
- package/src/commands/render.js +2 -0
- package/src/commands/render.js.map +1 -1
- package/src/commands/render.ts +6 -0
- package/src/embed/embed-snippet.d.ts +5 -0
- package/src/embed/embed-snippet.d.ts.map +1 -1
- package/src/embed/embed-snippet.js +6 -1
- package/src/embed/embed-snippet.js.map +1 -1
- package/src/embed/embed-snippet.ts +6 -1
- package/src/index.d.ts.map +1 -1
- package/src/index.js +2 -0
- package/src/index.js.map +1 -1
- package/src/index.ts +2 -0
- package/src/narrate/run-narrate.d.ts +15 -1
- package/src/narrate/run-narrate.d.ts.map +1 -1
- package/src/narrate/run-narrate.js +11 -4
- package/src/narrate/run-narrate.js.map +1 -1
- package/src/narrate/run-narrate.ts +15 -6
- package/src/pack/bundle-contract.d.ts +1 -0
- package/src/pack/bundle-contract.d.ts.map +1 -1
- package/src/pack/bundle-contract.js +3 -0
- package/src/pack/bundle-contract.js.map +1 -1
- package/src/pack/bundle-contract.ts +3 -0
- package/src/pack/collect-pack-shots.d.ts +16 -5
- package/src/pack/collect-pack-shots.d.ts.map +1 -1
- package/src/pack/collect-pack-shots.js +13 -4
- package/src/pack/collect-pack-shots.js.map +1 -1
- package/src/pack/collect-pack-shots.ts +35 -8
- package/src/pack/generate-embed-entry.d.ts +7 -0
- package/src/pack/generate-embed-entry.d.ts.map +1 -1
- package/src/pack/generate-embed-entry.js +105 -7
- package/src/pack/generate-embed-entry.js.map +1 -1
- package/src/pack/generate-embed-entry.ts +110 -7
- package/src/pack/run-pack.d.ts +8 -2
- package/src/pack/run-pack.d.ts.map +1 -1
- package/src/pack/run-pack.js +120 -17
- package/src/pack/run-pack.js.map +1 -1
- package/src/pack/run-pack.ts +164 -19
- package/src/pack/viewport.d.ts +17 -0
- package/src/pack/viewport.d.ts.map +1 -1
- package/src/pack/viewport.js +19 -0
- package/src/pack/viewport.js.map +1 -1
- package/src/pack/viewport.ts +29 -0
- package/src/presenter/heygen-client.d.ts +69 -0
- package/src/presenter/heygen-client.d.ts.map +1 -0
- package/src/presenter/heygen-client.js +154 -0
- package/src/presenter/heygen-client.js.map +1 -0
- package/src/presenter/heygen-client.ts +224 -0
- package/src/presenter/run-presenter.d.ts +67 -0
- package/src/presenter/run-presenter.d.ts.map +1 -0
- package/src/presenter/run-presenter.js +348 -0
- package/src/presenter/run-presenter.js.map +1 -0
- package/src/presenter/run-presenter.ts +536 -0
- package/src/render/generate-entry.d.ts +4 -0
- package/src/render/generate-entry.d.ts.map +1 -1
- package/src/render/generate-entry.js +75 -7
- package/src/render/generate-entry.js.map +1 -1
- package/src/render/generate-entry.ts +84 -7
- package/src/render/run-render.d.ts +6 -0
- package/src/render/run-render.d.ts.map +1 -1
- package/src/render/run-render.js +58 -0
- package/src/render/run-render.js.map +1 -1
- package/src/render/run-render.ts +72 -0
- package/src/render/stage-assets.d.ts +44 -0
- package/src/render/stage-assets.d.ts.map +1 -0
- package/src/render/stage-assets.js +91 -0
- package/src/render/stage-assets.js.map +1 -0
- package/src/render/stage-assets.ts +130 -0
- package/src/tts/echogarden.d.ts.map +1 -1
- package/src/tts/echogarden.js +4 -2
- package/src/tts/echogarden.js.map +1 -1
- package/src/tts/echogarden.ts +5 -2
- package/src/tts/edge-tts.d.ts.map +1 -1
- package/src/tts/edge-tts.js +2 -1
- package/src/tts/edge-tts.js.map +1 -1
- package/src/tts/edge-tts.ts +2 -1
- package/src/tts/elevenlabs.d.ts +15 -0
- package/src/tts/elevenlabs.d.ts.map +1 -0
- package/src/tts/elevenlabs.js +73 -0
- package/src/tts/elevenlabs.js.map +1 -0
- package/src/tts/elevenlabs.ts +105 -0
- package/src/tts/openai.d.ts.map +1 -1
- package/src/tts/openai.js +2 -1
- package/src/tts/openai.js.map +1 -1
- package/src/tts/openai.ts +2 -1
- package/src/tts/resolve-provider.d.ts +1 -1
- package/src/tts/resolve-provider.d.ts.map +1 -1
- package/src/tts/resolve-provider.js +10 -3
- package/src/tts/resolve-provider.js.map +1 -1
- package/src/tts/resolve-provider.ts +12 -4
- package/src/tts/types.d.ts +9 -0
- package/src/tts/types.d.ts.map +1 -1
- package/src/tts/types.ts +10 -0
- package/src/util/confirm.d.ts +11 -0
- package/src/util/confirm.d.ts.map +1 -0
- package/src/util/confirm.js +24 -0
- package/src/util/confirm.js.map +1 -0
- package/src/util/confirm.ts +23 -0
- package/src/util/load-bundle.d.ts +17 -1
- package/src/util/load-bundle.d.ts.map +1 -1
- package/src/util/load-bundle.js +19 -11
- package/src/util/load-bundle.js.map +1 -1
- package/src/util/load-bundle.ts +38 -12
- package/src/util/load-ts.d.ts +100 -0
- package/src/util/load-ts.d.ts.map +1 -1
- package/src/util/load-ts.js +176 -0
- package/src/util/load-ts.js.map +1 -1
- package/src/util/load-ts.ts +227 -0
- package/src/util/narration-cache.d.ts +13 -5
- package/src/util/narration-cache.d.ts.map +1 -1
- package/src/util/narration-cache.js +10 -8
- package/src/util/narration-cache.js.map +1 -1
- package/src/util/narration-cache.ts +22 -6
- package/src/util/presenter-cache.d.ts +44 -0
- package/src/util/presenter-cache.d.ts.map +1 -0
- package/src/util/presenter-cache.js +43 -0
- package/src/util/presenter-cache.js.map +1 -0
- package/src/util/presenter-cache.ts +101 -0
- package/src/util/scenario-assets.d.ts +47 -0
- package/src/util/scenario-assets.d.ts.map +1 -0
- package/src/util/scenario-assets.js +71 -0
- package/src/util/scenario-assets.js.map +1 -0
- package/src/util/scenario-assets.ts +111 -0
- package/src/util/soundtrack-assets.d.ts +34 -0
- package/src/util/soundtrack-assets.d.ts.map +1 -0
- package/src/util/soundtrack-assets.js +48 -0
- package/src/util/soundtrack-assets.js.map +1 -0
- package/src/util/soundtrack-assets.ts +69 -0
- package/src/validate/scenario-validator.d.ts.map +1 -1
- package/src/validate/scenario-validator.js +82 -0
- package/src/validate/scenario-validator.js.map +1 -1
- package/src/validate/scenario-validator.ts +110 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/example-bundle/assets/index-DlmG1Uh7.js +0 -388
- package/example-bundle/assets/style-BjquDnTE.css +0 -1
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { confirm } from "../util/confirm.js";
|
|
2
|
+
import { runPresenter } from "../presenter/run-presenter.js";
|
|
3
|
+
const ENGINES = new Set(["iii", "iv"]);
|
|
4
|
+
const RESOLUTIONS = new Set(["720p", "1080p"]);
|
|
5
|
+
export function registerPresenterCommand(program) {
|
|
6
|
+
program
|
|
7
|
+
.command("presenter")
|
|
8
|
+
.description("Generate presenter avatar clips from narration audio (HeyGen).\n\n" +
|
|
9
|
+
"For each step marked `presenter: true`, uploads the step's\n" +
|
|
10
|
+
"narration audio, generates a lip-synced avatar clip, and writes\n" +
|
|
11
|
+
"presenter/manifest.json beside the narration output. Run\n" +
|
|
12
|
+
"'scenar narrate' first — clips are derived from narration audio.\n\n" +
|
|
13
|
+
"This command calls a paid API: the batch estimate is printed and\n" +
|
|
14
|
+
"confirmed before any generation (skip the prompt with --yes).\n" +
|
|
15
|
+
"Requires HEYGEN_API_KEY.")
|
|
16
|
+
.argument("<file-or-dir>", "path to scenario file (.yaml/.ts) or directory")
|
|
17
|
+
.option("--avatar <id>", "HeyGen avatar id (fallback: HEYGEN_AVATAR_ID env)")
|
|
18
|
+
.option("--engine <engine>", "generation engine: iii or iv", "iii")
|
|
19
|
+
.option("--resolution <tier>", "output resolution: 720p or 1080p", "720p")
|
|
20
|
+
.option("--out <dir>", "output directory for clips")
|
|
21
|
+
.option("--base-url <path>", "URL path prefix for src fields in manifest")
|
|
22
|
+
.option("--yes", "skip the cost confirmation (CI / scripts)")
|
|
23
|
+
.action(async (fileOrDir, options) => {
|
|
24
|
+
try {
|
|
25
|
+
if (!ENGINES.has(options.engine)) {
|
|
26
|
+
throw new Error(`Unknown engine '${options.engine}'. Use iii or iv.`);
|
|
27
|
+
}
|
|
28
|
+
if (!RESOLUTIONS.has(options.resolution)) {
|
|
29
|
+
throw new Error(`Unknown resolution '${options.resolution}'. Use 720p or 1080p.`);
|
|
30
|
+
}
|
|
31
|
+
const result = await runPresenter({
|
|
32
|
+
target: fileOrDir,
|
|
33
|
+
avatar: options.avatar,
|
|
34
|
+
engine: options.engine,
|
|
35
|
+
resolution: options.resolution,
|
|
36
|
+
out: options.out,
|
|
37
|
+
baseUrl: options.baseUrl,
|
|
38
|
+
yes: options.yes,
|
|
39
|
+
confirmImpl: confirm,
|
|
40
|
+
onLog: (message) => process.stderr.write(`${message}\n`),
|
|
41
|
+
});
|
|
42
|
+
if (result.aborted) {
|
|
43
|
+
process.exitCode = 1;
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
if (result.mode === "file") {
|
|
47
|
+
const only = result.scenarios[0];
|
|
48
|
+
if (only?.skipped) {
|
|
49
|
+
process.stderr.write("\x1b[33m!\x1b[0m No steps opt into the presenter (`presenter: true`). Nothing to generate.\n");
|
|
50
|
+
}
|
|
51
|
+
if (result.totalFailed > 0)
|
|
52
|
+
process.exitCode = 1;
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
// Directory mode: print the aggregate summary.
|
|
56
|
+
if (result.scenarios.length === 0) {
|
|
57
|
+
process.stderr.write("\x1b[33m!\x1b[0m No scenario directories with steps.ts found.\n");
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
const withPresenter = result.scenarios.filter((s) => !s.skipped).length;
|
|
61
|
+
process.stderr.write("\n");
|
|
62
|
+
process.stderr.write(`Scenarios with presenter steps: ${withPresenter}\n`);
|
|
63
|
+
process.stderr.write(`Clips generated: ${result.totalGenerated}\n`);
|
|
64
|
+
process.stderr.write(`Clips cached: ${result.totalCached}\n`);
|
|
65
|
+
process.stderr.write(`Scenarios skipped: ${result.totalSkipped}\n`);
|
|
66
|
+
if (result.totalFailed > 0 || result.errors.length > 0) {
|
|
67
|
+
if (result.errors.length > 0) {
|
|
68
|
+
process.stderr.write(`\n\x1b[31m${result.errors.length} scenario(s) failed:\x1b[0m\n`);
|
|
69
|
+
for (const { id, message } of result.errors) {
|
|
70
|
+
process.stderr.write(` - ${id}: ${message}\n`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (result.totalFailed > 0) {
|
|
74
|
+
process.stderr.write(`\n\x1b[31m${result.totalFailed} clip(s) failed to generate.\x1b[0m\n`);
|
|
75
|
+
}
|
|
76
|
+
process.exitCode = 1;
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
process.stderr.write("\nDone\n");
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
84
|
+
process.stderr.write(`\x1b[31mError:\x1b[0m ${msg}\n`);
|
|
85
|
+
process.exitCode = 1;
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=presenter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"presenter.js","sourceRoot":"","sources":["../../../src/commands/presenter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { confirm } from "../util/confirm.js";
|
|
3
|
+
import { runPresenter } from "../presenter/run-presenter.js";
|
|
4
|
+
import type { HeygenEngineFlag } from "../presenter/heygen-client.js";
|
|
5
|
+
|
|
6
|
+
interface PresenterOptions {
|
|
7
|
+
avatar?: string;
|
|
8
|
+
engine: string;
|
|
9
|
+
resolution: string;
|
|
10
|
+
out?: string;
|
|
11
|
+
baseUrl?: string;
|
|
12
|
+
yes?: boolean;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const ENGINES = new Set<HeygenEngineFlag>(["iii", "iv"]);
|
|
16
|
+
const RESOLUTIONS = new Set(["720p", "1080p"]);
|
|
17
|
+
|
|
18
|
+
export function registerPresenterCommand(program: Command): void {
|
|
19
|
+
program
|
|
20
|
+
.command("presenter")
|
|
21
|
+
.description(
|
|
22
|
+
"Generate presenter avatar clips from narration audio (HeyGen).\n\n" +
|
|
23
|
+
"For each step marked `presenter: true`, uploads the step's\n" +
|
|
24
|
+
"narration audio, generates a lip-synced avatar clip, and writes\n" +
|
|
25
|
+
"presenter/manifest.json beside the narration output. Run\n" +
|
|
26
|
+
"'scenar narrate' first — clips are derived from narration audio.\n\n" +
|
|
27
|
+
"This command calls a paid API: the batch estimate is printed and\n" +
|
|
28
|
+
"confirmed before any generation (skip the prompt with --yes).\n" +
|
|
29
|
+
"Requires HEYGEN_API_KEY.",
|
|
30
|
+
)
|
|
31
|
+
.argument("<file-or-dir>", "path to scenario file (.yaml/.ts) or directory")
|
|
32
|
+
.option("--avatar <id>", "HeyGen avatar id (fallback: HEYGEN_AVATAR_ID env)")
|
|
33
|
+
.option("--engine <engine>", "generation engine: iii or iv", "iii")
|
|
34
|
+
.option("--resolution <tier>", "output resolution: 720p or 1080p", "720p")
|
|
35
|
+
.option("--out <dir>", "output directory for clips")
|
|
36
|
+
.option("--base-url <path>", "URL path prefix for src fields in manifest")
|
|
37
|
+
.option("--yes", "skip the cost confirmation (CI / scripts)")
|
|
38
|
+
.action(async (fileOrDir: string, options: PresenterOptions) => {
|
|
39
|
+
try {
|
|
40
|
+
if (!ENGINES.has(options.engine as HeygenEngineFlag)) {
|
|
41
|
+
throw new Error(`Unknown engine '${options.engine}'. Use iii or iv.`);
|
|
42
|
+
}
|
|
43
|
+
if (!RESOLUTIONS.has(options.resolution)) {
|
|
44
|
+
throw new Error(`Unknown resolution '${options.resolution}'. Use 720p or 1080p.`);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const result = await runPresenter({
|
|
48
|
+
target: fileOrDir,
|
|
49
|
+
avatar: options.avatar,
|
|
50
|
+
engine: options.engine as HeygenEngineFlag,
|
|
51
|
+
resolution: options.resolution,
|
|
52
|
+
out: options.out,
|
|
53
|
+
baseUrl: options.baseUrl,
|
|
54
|
+
yes: options.yes,
|
|
55
|
+
confirmImpl: confirm,
|
|
56
|
+
onLog: (message) => process.stderr.write(`${message}\n`),
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
if (result.aborted) {
|
|
60
|
+
process.exitCode = 1;
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (result.mode === "file") {
|
|
65
|
+
const only = result.scenarios[0];
|
|
66
|
+
if (only?.skipped) {
|
|
67
|
+
process.stderr.write(
|
|
68
|
+
"\x1b[33m!\x1b[0m No steps opt into the presenter (`presenter: true`). Nothing to generate.\n",
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
if (result.totalFailed > 0) process.exitCode = 1;
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Directory mode: print the aggregate summary.
|
|
76
|
+
if (result.scenarios.length === 0) {
|
|
77
|
+
process.stderr.write("\x1b[33m!\x1b[0m No scenario directories with steps.ts found.\n");
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
const withPresenter = result.scenarios.filter((s) => !s.skipped).length;
|
|
81
|
+
process.stderr.write("\n");
|
|
82
|
+
process.stderr.write(`Scenarios with presenter steps: ${withPresenter}\n`);
|
|
83
|
+
process.stderr.write(`Clips generated: ${result.totalGenerated}\n`);
|
|
84
|
+
process.stderr.write(`Clips cached: ${result.totalCached}\n`);
|
|
85
|
+
process.stderr.write(`Scenarios skipped: ${result.totalSkipped}\n`);
|
|
86
|
+
|
|
87
|
+
if (result.totalFailed > 0 || result.errors.length > 0) {
|
|
88
|
+
if (result.errors.length > 0) {
|
|
89
|
+
process.stderr.write(`\n\x1b[31m${result.errors.length} scenario(s) failed:\x1b[0m\n`);
|
|
90
|
+
for (const { id, message } of result.errors) {
|
|
91
|
+
process.stderr.write(` - ${id}: ${message}\n`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
if (result.totalFailed > 0) {
|
|
95
|
+
process.stderr.write(`\n\x1b[31m${result.totalFailed} clip(s) failed to generate.\x1b[0m\n`);
|
|
96
|
+
}
|
|
97
|
+
process.exitCode = 1;
|
|
98
|
+
} else {
|
|
99
|
+
process.stderr.write("\nDone\n");
|
|
100
|
+
}
|
|
101
|
+
} catch (error) {
|
|
102
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
103
|
+
process.stderr.write(`\x1b[31mError:\x1b[0m ${msg}\n`);
|
|
104
|
+
process.exitCode = 1;
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../../src/commands/render.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../../src/commands/render.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAcpC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAkD5D"}
|
package/src/commands/render.js
CHANGED
|
@@ -16,6 +16,7 @@ export function registerRenderCommand(program) {
|
|
|
16
16
|
.option("--width <number>", "video width in pixels (default: 1920)", "1920")
|
|
17
17
|
.option("--height <number>", "video height in pixels (default: 1080)", "1080")
|
|
18
18
|
.option("--composition-id <id>", "Remotion composition ID to render")
|
|
19
|
+
.option("--captions", "burn step captions into the video (each step's narration text)")
|
|
19
20
|
.option("--entry <path>", "path to a custom Remotion entry file")
|
|
20
21
|
.option("--webpack-override <path>", "path to a module that default-exports a Remotion WebpackOverrideFn")
|
|
21
22
|
.action(async (dir, options) => {
|
|
@@ -29,6 +30,7 @@ export function registerRenderCommand(program) {
|
|
|
29
30
|
compositionId: options.compositionId,
|
|
30
31
|
entry: options.entry,
|
|
31
32
|
webpackOverride: options.webpackOverride,
|
|
33
|
+
captions: options.captions ?? false,
|
|
32
34
|
onLog: (message) => process.stderr.write(`${message}\n`),
|
|
33
35
|
});
|
|
34
36
|
process.stderr.write(`\n\x1b[32m✓\x1b[0m Video saved to ${result.outputPath}\n`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render.js","sourceRoot":"","sources":["../../../src/commands/render.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"render.js","sourceRoot":"","sources":["../../../src/commands/render.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAapD,MAAM,UAAU,qBAAqB,CAAC,OAAgB;IACpD,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CACV,uDAAuD;QACrD,oEAAoE;QACpE,4DAA4D;QAC5D,oEAAoE;QACpE,kEAAkE;QAClE,yDAAyD;QACzD,iEAAiE;QACjE,oDAAoD,CACvD;SACA,QAAQ,CAAC,OAAO,EAAE,sDAAsD,CAAC;SACzE,MAAM,CAAC,cAAc,EAAE,2CAA2C,CAAC;SACnE,MAAM,CAAC,gBAAgB,EAAE,iCAAiC,EAAE,IAAI,CAAC;SACjE,MAAM,CAAC,kBAAkB,EAAE,uCAAuC,EAAE,MAAM,CAAC;SAC3E,MAAM,CAAC,mBAAmB,EAAE,wCAAwC,EAAE,MAAM,CAAC;SAC7E,MAAM,CAAC,uBAAuB,EAAE,mCAAmC,CAAC;SACpE,MAAM,CACL,YAAY,EACZ,gEAAgE,CACjE;SACA,MAAM,CAAC,gBAAgB,EAAE,sCAAsC,CAAC;SAChE,MAAM,CACL,2BAA2B,EAC3B,oEAAoE,CACrE;SACA,MAAM,CAAC,KAAK,EAAE,GAAW,EAAE,OAAsB,EAAE,EAAE;QACpD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC;gBAC7B,WAAW,EAAE,GAAG;gBAChB,GAAG,EAAE,OAAO,CAAC,GAAG;gBAChB,GAAG,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE;gBAC9B,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,IAAI;gBACpC,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,IAAI;gBACtC,aAAa,EAAE,OAAO,CAAC,aAAa;gBACpC,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,eAAe,EAAE,OAAO,CAAC,eAAe;gBACxC,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,KAAK;gBACnC,KAAK,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,OAAO,IAAI,CAAC;aACzD,CAAC,CAAC;YAEH,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,qCAAqC,MAAM,CAAC,UAAU,IAAI,CAAC,CAAC;QACnF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,GAAG,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACnE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,yBAAyB,GAAG,IAAI,CAAC,CAAC;YACvD,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACvB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
|
package/src/commands/render.ts
CHANGED
|
@@ -9,6 +9,7 @@ interface RenderOptions {
|
|
|
9
9
|
compositionId?: string;
|
|
10
10
|
entry?: string;
|
|
11
11
|
webpackOverride?: string;
|
|
12
|
+
captions?: boolean;
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
export function registerRenderCommand(program: Command): void {
|
|
@@ -30,6 +31,10 @@ export function registerRenderCommand(program: Command): void {
|
|
|
30
31
|
.option("--width <number>", "video width in pixels (default: 1920)", "1920")
|
|
31
32
|
.option("--height <number>", "video height in pixels (default: 1080)", "1080")
|
|
32
33
|
.option("--composition-id <id>", "Remotion composition ID to render")
|
|
34
|
+
.option(
|
|
35
|
+
"--captions",
|
|
36
|
+
"burn step captions into the video (each step's narration text)",
|
|
37
|
+
)
|
|
33
38
|
.option("--entry <path>", "path to a custom Remotion entry file")
|
|
34
39
|
.option(
|
|
35
40
|
"--webpack-override <path>",
|
|
@@ -46,6 +51,7 @@ export function registerRenderCommand(program: Command): void {
|
|
|
46
51
|
compositionId: options.compositionId,
|
|
47
52
|
entry: options.entry,
|
|
48
53
|
webpackOverride: options.webpackOverride,
|
|
54
|
+
captions: options.captions ?? false,
|
|
49
55
|
onLog: (message) => process.stderr.write(`${message}\n`),
|
|
50
56
|
});
|
|
51
57
|
|
|
@@ -21,6 +21,11 @@ export interface EmbedSnippetInput {
|
|
|
21
21
|
* verbatim. Attribute values are escaped, since the snippet is copy-pasted into
|
|
22
22
|
* third-party HTML.
|
|
23
23
|
*
|
|
24
|
+
* The wrapper carries `overflow:hidden` so it honors the embed corner contract:
|
|
25
|
+
* a host that adds `border-radius` to the wrapper gets cleanly clipped corners
|
|
26
|
+
* (the embed paints edge-to-edge; the host boundary owns the radius, same as
|
|
27
|
+
* `@scenar/embed`'s adapters).
|
|
28
|
+
*
|
|
24
29
|
* Pure function — returns the snippet string; the caller decides where to print.
|
|
25
30
|
*/
|
|
26
31
|
export declare function buildEmbedSnippet(input: EmbedSnippetInput): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"embed-snippet.d.ts","sourceRoot":"","sources":["../../../src/embed/embed-snippet.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEpD,4CAA4C;AAC5C,MAAM,WAAW,iBAAiB;IAChC,2EAA2E;IAC3E,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,+EAA+E;IAC/E,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,+EAA+E;IAC/E,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED
|
|
1
|
+
{"version":3,"file":"embed-snippet.d.ts","sourceRoot":"","sources":["../../../src/embed/embed-snippet.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEpD,4CAA4C;AAC5C,MAAM,WAAW,iBAAiB;IAChC,2EAA2E;IAC3E,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,+EAA+E;IAC/E,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,+EAA+E;IAC/E,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,CAelE;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,CAW1E"}
|
|
@@ -11,13 +11,18 @@
|
|
|
11
11
|
* verbatim. Attribute values are escaped, since the snippet is copy-pasted into
|
|
12
12
|
* third-party HTML.
|
|
13
13
|
*
|
|
14
|
+
* The wrapper carries `overflow:hidden` so it honors the embed corner contract:
|
|
15
|
+
* a host that adds `border-radius` to the wrapper gets cleanly clipped corners
|
|
16
|
+
* (the embed paints edge-to-edge; the host boundary owns the radius, same as
|
|
17
|
+
* `@scenar/embed`'s adapters).
|
|
18
|
+
*
|
|
14
19
|
* Pure function — returns the snippet string; the caller decides where to print.
|
|
15
20
|
*/
|
|
16
21
|
export function buildEmbedSnippet(input) {
|
|
17
22
|
const { embedUrl, viewport } = input;
|
|
18
23
|
const title = input.title ?? "Scenar embed";
|
|
19
24
|
return [
|
|
20
|
-
`<div style="position:relative;width:100%;max-width:${viewport.width}px;aspect-ratio:${viewport.width}/${viewport.height}">`,
|
|
25
|
+
`<div style="position:relative;width:100%;max-width:${viewport.width}px;aspect-ratio:${viewport.width}/${viewport.height};overflow:hidden">`,
|
|
21
26
|
` <iframe`,
|
|
22
27
|
` src="${escapeAttr(embedUrl)}"`,
|
|
23
28
|
` title="${escapeAttr(title)}"`,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"embed-snippet.js","sourceRoot":"","sources":["../../../src/embed/embed-snippet.ts"],"names":[],"mappings":"AAYA
|
|
1
|
+
{"version":3,"file":"embed-snippet.js","sourceRoot":"","sources":["../../../src/embed/embed-snippet.ts"],"names":[],"mappings":"AAYA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAwB;IACxD,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC;IACrC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,IAAI,cAAc,CAAC;IAC5C,OAAO;QACL,sDAAsD,QAAQ,CAAC,KAAK,mBAAmB,QAAQ,CAAC,KAAK,IAAI,QAAQ,CAAC,MAAM,oBAAoB;QAC5I,WAAW;QACX,YAAY,UAAU,CAAC,QAAQ,CAAC,GAAG;QACnC,cAAc,UAAU,CAAC,KAAK,CAAC,GAAG;QAClC,oBAAoB;QACpB,uEAAuE;QACvE,kCAAkC;QAClC,qBAAqB;QACrB,cAAc;QACd,QAAQ;KACT,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,yBAAyB,CAAC,KAAwB;IAChE,MAAM,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC;IAC3B,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,IAAI,cAAc,CAAC;IAC5C,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC,QAAQ,EAAE,CAAC;IAC3D,OAAO;QACL,8BAA8B,UAAU,CAAC,SAAS,CAAC,aAAa;QAChE,eAAe;QACf,UAAU,UAAU,CAAC,QAAQ,CAAC,GAAG;QACjC,YAAY,UAAU,CAAC,KAAK,CAAC,GAAG;QAChC,kBAAkB;KACnB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,kFAAkF;AAClF,SAAS,UAAU,CAAC,KAAa;IAC/B,OAAO,KAAK;SACT,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC;SACvB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AAC3B,CAAC"}
|
|
@@ -23,13 +23,18 @@ export interface EmbedSnippetInput {
|
|
|
23
23
|
* verbatim. Attribute values are escaped, since the snippet is copy-pasted into
|
|
24
24
|
* third-party HTML.
|
|
25
25
|
*
|
|
26
|
+
* The wrapper carries `overflow:hidden` so it honors the embed corner contract:
|
|
27
|
+
* a host that adds `border-radius` to the wrapper gets cleanly clipped corners
|
|
28
|
+
* (the embed paints edge-to-edge; the host boundary owns the radius, same as
|
|
29
|
+
* `@scenar/embed`'s adapters).
|
|
30
|
+
*
|
|
26
31
|
* Pure function — returns the snippet string; the caller decides where to print.
|
|
27
32
|
*/
|
|
28
33
|
export function buildEmbedSnippet(input: EmbedSnippetInput): string {
|
|
29
34
|
const { embedUrl, viewport } = input;
|
|
30
35
|
const title = input.title ?? "Scenar embed";
|
|
31
36
|
return [
|
|
32
|
-
`<div style="position:relative;width:100%;max-width:${viewport.width}px;aspect-ratio:${viewport.width}/${viewport.height}">`,
|
|
37
|
+
`<div style="position:relative;width:100%;max-width:${viewport.width}px;aspect-ratio:${viewport.width}/${viewport.height};overflow:hidden">`,
|
|
33
38
|
` <iframe`,
|
|
34
39
|
` src="${escapeAttr(embedUrl)}"`,
|
|
35
40
|
` title="${escapeAttr(title)}"`,
|
package/src/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAYpC,wBAAgB,aAAa,IAAI,OAAO,CAoBvC;AAED,wBAAgB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAGxC"}
|
package/src/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
2
|
import { registerValidateCommand } from "./commands/validate.js";
|
|
3
3
|
import { registerNarrateCommand } from "./commands/narrate.js";
|
|
4
|
+
import { registerPresenterCommand } from "./commands/presenter.js";
|
|
4
5
|
import { registerInstallCommand } from "./commands/install.js";
|
|
5
6
|
import { registerRenderCommand } from "./commands/render.js";
|
|
6
7
|
import { registerPackCommand } from "./commands/pack.js";
|
|
@@ -16,6 +17,7 @@ export function createProgram() {
|
|
|
16
17
|
.version("0.0.1");
|
|
17
18
|
registerValidateCommand(program);
|
|
18
19
|
registerNarrateCommand(program);
|
|
20
|
+
registerPresenterCommand(program);
|
|
19
21
|
registerRenderCommand(program);
|
|
20
22
|
registerInstallCommand(program);
|
|
21
23
|
registerPackCommand(program);
|
package/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAE/D,MAAM,UAAU,aAAa;IAC3B,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAE9B,OAAO;SACJ,IAAI,CAAC,QAAQ,CAAC;SACd,WAAW,CAAC,+FAA+F,CAAC;SAC5G,OAAO,CAAC,OAAO,CAAC,CAAC;IAEpB,uBAAuB,CAAC,OAAO,CAAC,CAAC;IACjC,sBAAsB,CAAC,OAAO,CAAC,CAAC;IAChC,qBAAqB,CAAC,OAAO,CAAC,CAAC;IAC/B,sBAAsB,CAAC,OAAO,CAAC,CAAC;IAChC,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAC7B,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAC9B,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAC9B,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAC5B,sBAAsB,CAAC,OAAO,CAAC,CAAC;IAEhC,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,GAAG,CAAC,IAAc;IAChC,MAAM,OAAO,GAAG,aAAa,EAAE,CAAC;IAChC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AACtB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAE/D,MAAM,UAAU,aAAa;IAC3B,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAE9B,OAAO;SACJ,IAAI,CAAC,QAAQ,CAAC;SACd,WAAW,CAAC,+FAA+F,CAAC;SAC5G,OAAO,CAAC,OAAO,CAAC,CAAC;IAEpB,uBAAuB,CAAC,OAAO,CAAC,CAAC;IACjC,sBAAsB,CAAC,OAAO,CAAC,CAAC;IAChC,wBAAwB,CAAC,OAAO,CAAC,CAAC;IAClC,qBAAqB,CAAC,OAAO,CAAC,CAAC;IAC/B,sBAAsB,CAAC,OAAO,CAAC,CAAC;IAChC,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAC7B,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAC9B,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAC9B,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAC5B,sBAAsB,CAAC,OAAO,CAAC,CAAC;IAEhC,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,GAAG,CAAC,IAAc;IAChC,MAAM,OAAO,GAAG,aAAa,EAAE,CAAC;IAChC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AACtB,CAAC"}
|
package/src/index.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
2
|
import { registerValidateCommand } from "./commands/validate.js";
|
|
3
3
|
import { registerNarrateCommand } from "./commands/narrate.js";
|
|
4
|
+
import { registerPresenterCommand } from "./commands/presenter.js";
|
|
4
5
|
import { registerInstallCommand } from "./commands/install.js";
|
|
5
6
|
import { registerRenderCommand } from "./commands/render.js";
|
|
6
7
|
import { registerPackCommand } from "./commands/pack.js";
|
|
@@ -19,6 +20,7 @@ export function createProgram(): Command {
|
|
|
19
20
|
|
|
20
21
|
registerValidateCommand(program);
|
|
21
22
|
registerNarrateCommand(program);
|
|
23
|
+
registerPresenterCommand(program);
|
|
22
24
|
registerRenderCommand(program);
|
|
23
25
|
registerInstallCommand(program);
|
|
24
26
|
registerPackCommand(program);
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
export interface RunNarrateOptions {
|
|
3
3
|
/** A scenario YAML file, a .ts steps file, or a directory of scenarios. */
|
|
4
4
|
readonly target: string;
|
|
5
|
-
/** TTS provider name: echogarden, edge-tts, or
|
|
5
|
+
/** TTS provider name: echogarden, edge-tts, openai, or elevenlabs (default echogarden). */
|
|
6
6
|
readonly tts?: string;
|
|
7
7
|
/** Output directory for audio (default: alongside the scenario). */
|
|
8
8
|
readonly out?: string;
|
|
@@ -33,6 +33,20 @@ export interface NarrateResult {
|
|
|
33
33
|
message: string;
|
|
34
34
|
}>;
|
|
35
35
|
}
|
|
36
|
+
/**
|
|
37
|
+
* Load authored steps from a scenario file — the shared entry point of
|
|
38
|
+
* the compile commands (`scenar narrate`, `scenar presenter`): a
|
|
39
|
+
* TypeScript steps file loads as-is; a YAML scenario is validated and
|
|
40
|
+
* its (camelized) steps returned.
|
|
41
|
+
*/
|
|
42
|
+
export declare function loadStepsFromFile(filePath: string): Promise<{
|
|
43
|
+
steps: Array<{
|
|
44
|
+
narration?: string;
|
|
45
|
+
narrationText?: string;
|
|
46
|
+
presenter?: boolean;
|
|
47
|
+
}>;
|
|
48
|
+
totalSteps: number;
|
|
49
|
+
}>;
|
|
36
50
|
/**
|
|
37
51
|
* Generate narration audio for a scenario file or a directory of scenarios —
|
|
38
52
|
* the pure orchestration behind `scenar narrate`. Resolves the TTS provider,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-narrate.d.ts","sourceRoot":"","sources":["../../../src/narrate/run-narrate.ts"],"names":[],"mappings":"AAkBA,4EAA4E;AAC5E,MAAM,WAAW,iBAAiB;IAChC,2EAA2E;IAC3E,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB
|
|
1
|
+
{"version":3,"file":"run-narrate.d.ts","sourceRoot":"","sources":["../../../src/narrate/run-narrate.ts"],"names":[],"mappings":"AAkBA,4EAA4E;AAC5E,MAAM,WAAW,iBAAiB;IAChC,2EAA2E;IAC3E,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,2FAA2F;IAC3F,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,oEAAoE;IACpE,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,sCAAsC;IACtC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,sEAAsE;IACtE,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,wDAAwD;IACxD,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CAC5C;AAED,sCAAsC;AACtC,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,4EAA4E;IAC5E,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B;AAED,yCAAyC;AACzC,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IACpC,QAAQ,CAAC,SAAS,EAAE,gBAAgB,EAAE,CAAC;IACvC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACzD;AAwCD;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;IAAE,KAAK,EAAE,KAAK,CAAC;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,CAuBpH;AAoED;;;;;GAKG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,aAAa,CAAC,CASnF"}
|
|
@@ -23,7 +23,13 @@ function buildRuntimeManifest(totalSteps, entries) {
|
|
|
23
23
|
}
|
|
24
24
|
return { steps };
|
|
25
25
|
}
|
|
26
|
-
|
|
26
|
+
/**
|
|
27
|
+
* Load authored steps from a scenario file — the shared entry point of
|
|
28
|
+
* the compile commands (`scenar narrate`, `scenar presenter`): a
|
|
29
|
+
* TypeScript steps file loads as-is; a YAML scenario is validated and
|
|
30
|
+
* its (camelized) steps returned.
|
|
31
|
+
*/
|
|
32
|
+
export async function loadStepsFromFile(filePath) {
|
|
27
33
|
const ext = extname(filePath).toLowerCase();
|
|
28
34
|
if (ext === ".ts" || ext === ".tsx") {
|
|
29
35
|
const steps = await loadStepsFromTs(filePath);
|
|
@@ -48,12 +54,13 @@ async function generateNarration(opts) {
|
|
|
48
54
|
const manifestEntries = new Map();
|
|
49
55
|
const cacheEntries = new Map();
|
|
50
56
|
for (const step of narratedSteps) {
|
|
51
|
-
const hash = computeHash(step.text, voice);
|
|
57
|
+
const hash = computeHash(step.text, voice, provider.fingerprint);
|
|
52
58
|
const fileName = `step-${step.index}.mp3`;
|
|
53
59
|
const mp3Path = join(outDir, fileName);
|
|
54
60
|
const srcPrefix = baseUrl ? `${baseUrl.replace(/\/$/, "")}/${scenarioId}` : `.`;
|
|
55
61
|
const src = `${srcPrefix}/${fileName}`;
|
|
56
|
-
if (isCached(existingCache, step.index, hash, voice) &&
|
|
62
|
+
if (isCached(existingCache, step.index, hash, voice, provider.fingerprint) &&
|
|
63
|
+
(await fileExists(mp3Path))) {
|
|
57
64
|
const durationMs = getCachedDuration(existingCache, step.index);
|
|
58
65
|
manifestEntries.set(step.index, { src, durationMs });
|
|
59
66
|
cacheEntries.set(step.index, { hash, durationMs });
|
|
@@ -71,7 +78,7 @@ async function generateNarration(opts) {
|
|
|
71
78
|
}
|
|
72
79
|
const manifest = buildRuntimeManifest(totalSteps, manifestEntries);
|
|
73
80
|
await writeFile(join(outDir, "manifest.json"), JSON.stringify(manifest, null, 2) + "\n");
|
|
74
|
-
const cache = buildCacheFile(voice, totalSteps, cacheEntries);
|
|
81
|
+
const cache = buildCacheFile(provider.fingerprint, voice, totalSteps, cacheEntries);
|
|
75
82
|
await saveCache(outDir, cache);
|
|
76
83
|
onLog(`\x1b[32m+\x1b[0m ${scenarioId}: ${stats.generated} generated, ${stats.cached} cached`);
|
|
77
84
|
return stats;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-narrate.js","sourceRoot":"","sources":["../../../src/narrate/run-narrate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACtE,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,EACL,WAAW,EACX,SAAS,EACT,SAAS,EACT,UAAU,EACV,QAAQ,EACR,iBAAiB,EACjB,cAAc,GACf,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AA2C7D,SAAS,oBAAoB,CAC3B,KAA4D;IAE5D,MAAM,MAAM,GAAwB,EAAE,CAAC;IACvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC,SAAS,IAAI,KAAK,CAAC,CAAC,CAAE,CAAC,aAAa,CAAC;QAC5D,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAChD,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAWD,SAAS,oBAAoB,CAC3B,UAAkB,EAClB,OAAyD;IAEzD,MAAM,KAAK,GAAoC,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;IAC9F,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,OAAO,EAAE,CAAC;QACnC,KAAK,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IACrB,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,CAAC;AACnB,CAAC;AAED,KAAK,UAAU,iBAAiB,
|
|
1
|
+
{"version":3,"file":"run-narrate.js","sourceRoot":"","sources":["../../../src/narrate/run-narrate.ts"],"names":[],"mappings":"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"}
|
|
@@ -20,7 +20,7 @@ import type { TtsProvider } from "../tts/types.js";
|
|
|
20
20
|
export interface RunNarrateOptions {
|
|
21
21
|
/** A scenario YAML file, a .ts steps file, or a directory of scenarios. */
|
|
22
22
|
readonly target: string;
|
|
23
|
-
/** TTS provider name: echogarden, edge-tts, or
|
|
23
|
+
/** TTS provider name: echogarden, edge-tts, openai, or elevenlabs (default echogarden). */
|
|
24
24
|
readonly tts?: string;
|
|
25
25
|
/** Output directory for audio (default: alongside the scenario). */
|
|
26
26
|
readonly out?: string;
|
|
@@ -89,9 +89,15 @@ function buildRuntimeManifest(
|
|
|
89
89
|
return { steps };
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
-
|
|
92
|
+
/**
|
|
93
|
+
* Load authored steps from a scenario file — the shared entry point of
|
|
94
|
+
* the compile commands (`scenar narrate`, `scenar presenter`): a
|
|
95
|
+
* TypeScript steps file loads as-is; a YAML scenario is validated and
|
|
96
|
+
* its (camelized) steps returned.
|
|
97
|
+
*/
|
|
98
|
+
export async function loadStepsFromFile(
|
|
93
99
|
filePath: string,
|
|
94
|
-
): Promise<{ steps: Array<{ narration?: string; narrationText?: string }>; totalSteps: number }> {
|
|
100
|
+
): Promise<{ steps: Array<{ narration?: string; narrationText?: string; presenter?: boolean }>; totalSteps: number }> {
|
|
95
101
|
const ext = extname(filePath).toLowerCase();
|
|
96
102
|
|
|
97
103
|
if (ext === ".ts" || ext === ".tsx") {
|
|
@@ -143,14 +149,17 @@ async function generateNarration(opts: GenerateOptions): Promise<GenerateStats>
|
|
|
143
149
|
const cacheEntries = new Map<number, { hash: string; durationMs: number }>();
|
|
144
150
|
|
|
145
151
|
for (const step of narratedSteps) {
|
|
146
|
-
const hash = computeHash(step.text, voice);
|
|
152
|
+
const hash = computeHash(step.text, voice, provider.fingerprint);
|
|
147
153
|
const fileName = `step-${step.index}.mp3`;
|
|
148
154
|
const mp3Path = join(outDir, fileName);
|
|
149
155
|
|
|
150
156
|
const srcPrefix = baseUrl ? `${baseUrl.replace(/\/$/, "")}/${scenarioId}` : `.`;
|
|
151
157
|
const src = `${srcPrefix}/${fileName}`;
|
|
152
158
|
|
|
153
|
-
if (
|
|
159
|
+
if (
|
|
160
|
+
isCached(existingCache, step.index, hash, voice, provider.fingerprint) &&
|
|
161
|
+
(await fileExists(mp3Path))
|
|
162
|
+
) {
|
|
154
163
|
const durationMs = getCachedDuration(existingCache!, step.index);
|
|
155
164
|
manifestEntries.set(step.index, { src, durationMs });
|
|
156
165
|
cacheEntries.set(step.index, { hash, durationMs });
|
|
@@ -172,7 +181,7 @@ async function generateNarration(opts: GenerateOptions): Promise<GenerateStats>
|
|
|
172
181
|
const manifest = buildRuntimeManifest(totalSteps, manifestEntries);
|
|
173
182
|
await writeFile(join(outDir, "manifest.json"), JSON.stringify(manifest, null, 2) + "\n");
|
|
174
183
|
|
|
175
|
-
const cache = buildCacheFile(voice, totalSteps, cacheEntries);
|
|
184
|
+
const cache = buildCacheFile(provider.fingerprint, voice, totalSteps, cacheEntries);
|
|
176
185
|
await saveCache(outDir, cache);
|
|
177
186
|
|
|
178
187
|
onLog(`\x1b[32m+\x1b[0m ${scenarioId}: ${stats.generated} generated, ${stats.cached} cached`);
|
|
@@ -25,6 +25,7 @@ export declare const CONTENT_TYPE_BY_EXTENSION: {
|
|
|
25
25
|
readonly css: "text/css";
|
|
26
26
|
readonly json: "application/json";
|
|
27
27
|
readonly mp3: "audio/mpeg";
|
|
28
|
+
readonly mp4: "video/mp4";
|
|
28
29
|
readonly png: "image/png";
|
|
29
30
|
readonly jpg: "image/jpeg";
|
|
30
31
|
readonly jpeg: "image/jpeg";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bundle-contract.d.ts","sourceRoot":"","sources":["../../../src/pack/bundle-contract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,oFAAoF;AACpF,eAAO,MAAM,yBAAyB
|
|
1
|
+
{"version":3,"file":"bundle-contract.d.ts","sourceRoot":"","sources":["../../../src/pack/bundle-contract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,oFAAoF;AACpF,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;CAoB5B,CAAC;AAEX,0FAA0F;AAC1F,eAAO,MAAM,kBAAkB,EAE1B,CAAC,MAAM,OAAO,yBAAyB,CAAC,EAAE,CAAC;AAEhD,sFAAsF;AACtF,eAAO,MAAM,qBAAqB,QAA0C,CAAC;AAE7E,4EAA4E;AAC5E,eAAO,MAAM,cAAc,KAAK,CAAC;AAEjC,6EAA6E;AAC7E,eAAO,MAAM,kBAAkB,QAAmB,CAAC;AAEnD,8EAA8E;AAC9E,eAAO,MAAM,oBAAoB,QAAuB,CAAC;AAEzD,sDAAsD;AACtD,eAAO,MAAM,aAAa,kBAAkB,CAAC;AAQ7C,+EAA+E;AAC/E,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAInD;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAoBhE;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAuB/D"}
|
|
@@ -26,6 +26,9 @@ export const CONTENT_TYPE_BY_EXTENSION = {
|
|
|
26
26
|
css: "text/css",
|
|
27
27
|
json: "application/json",
|
|
28
28
|
mp3: "audio/mpeg",
|
|
29
|
+
// Presenter clips (`scenar presenter`). mp4 only — no webm until the
|
|
30
|
+
// alpha-cutout follow-up earns it (Safari renders VP9 alpha opaque).
|
|
31
|
+
mp4: "video/mp4",
|
|
29
32
|
// Raster web images.
|
|
30
33
|
png: "image/png",
|
|
31
34
|
jpg: "image/jpeg",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bundle-contract.js","sourceRoot":"","sources":["../../../src/pack/bundle-contract.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"bundle-contract.js","sourceRoot":"","sources":["../../../src/pack/bundle-contract.ts"],"names":[],"mappings":"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"}
|
|
@@ -27,6 +27,9 @@ export const CONTENT_TYPE_BY_EXTENSION = {
|
|
|
27
27
|
css: "text/css",
|
|
28
28
|
json: "application/json",
|
|
29
29
|
mp3: "audio/mpeg",
|
|
30
|
+
// Presenter clips (`scenar presenter`). mp4 only — no webm until the
|
|
31
|
+
// alpha-cutout follow-up earns it (Safari renders VP9 alpha opaque).
|
|
32
|
+
mp4: "video/mp4",
|
|
30
33
|
// Raster web images.
|
|
31
34
|
png: "image/png",
|
|
32
35
|
jpg: "image/jpeg",
|