demo-reel 0.7.6 → 0.8.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/audio-processor.d.ts +2 -36
- package/dist/audio-processor.d.ts.map +1 -1
- package/dist/audio-processor.js +1 -166
- package/dist/audio-processor.js.map +1 -1
- package/dist/browser/launcher.d.ts +6 -0
- package/dist/browser/launcher.d.ts.map +1 -0
- package/dist/browser/launcher.js +46 -0
- package/dist/browser/launcher.js.map +1 -0
- package/dist/browser/pool.d.ts +14 -0
- package/dist/browser/pool.d.ts.map +1 -0
- package/dist/browser/pool.js +30 -0
- package/dist/browser/pool.js.map +1 -0
- package/dist/browser/types.d.ts +8 -0
- package/dist/browser/types.d.ts.map +1 -0
- package/dist/browser/types.js +2 -0
- package/dist/browser/types.js.map +1 -0
- package/dist/cli.d.ts +3 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +114 -60
- package/dist/cli.js.map +1 -1
- package/dist/commands/types.d.ts +1 -0
- package/dist/commands/types.d.ts.map +1 -1
- package/dist/ffmpeg/utils.d.ts +39 -0
- package/dist/ffmpeg/utils.d.ts.map +1 -0
- package/dist/ffmpeg/utils.js +274 -0
- package/dist/ffmpeg/utils.js.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +54 -154
- package/dist/index.js.map +1 -1
- package/dist/pipeline/context.d.ts +33 -0
- package/dist/pipeline/context.d.ts.map +1 -0
- package/dist/pipeline/context.js +28 -0
- package/dist/pipeline/context.js.map +1 -0
- package/dist/pipeline/orchestrator.d.ts +4 -0
- package/dist/pipeline/orchestrator.d.ts.map +1 -0
- package/dist/pipeline/orchestrator.js +8 -0
- package/dist/pipeline/orchestrator.js.map +1 -0
- package/dist/pipeline/types.d.ts +6 -0
- package/dist/pipeline/types.d.ts.map +1 -0
- package/dist/pipeline/types.js +2 -0
- package/dist/pipeline/types.js.map +1 -0
- package/dist/runner/assertions.d.ts +8 -0
- package/dist/runner/assertions.d.ts.map +1 -0
- package/dist/runner/assertions.js +73 -0
- package/dist/runner/assertions.js.map +1 -0
- package/dist/runner/cursor.d.ts +32 -0
- package/dist/runner/cursor.d.ts.map +1 -0
- package/dist/runner/cursor.js +179 -0
- package/dist/runner/cursor.js.map +1 -0
- package/dist/runner/index.d.ts +17 -0
- package/dist/runner/index.d.ts.map +1 -0
- package/dist/runner/index.js +189 -0
- package/dist/runner/index.js.map +1 -0
- package/dist/runner/motion.d.ts +18 -0
- package/dist/runner/motion.d.ts.map +1 -0
- package/dist/runner/motion.js +117 -0
- package/dist/runner/motion.js.map +1 -0
- package/dist/runner/scene-tracking.d.ts +5 -0
- package/dist/runner/scene-tracking.d.ts.map +1 -0
- package/dist/runner/scene-tracking.js +42 -0
- package/dist/runner/scene-tracking.js.map +1 -0
- package/dist/runner/selectors.d.ts +6 -0
- package/dist/runner/selectors.d.ts.map +1 -0
- package/dist/runner/selectors.js +34 -0
- package/dist/runner/selectors.js.map +1 -0
- package/dist/runner/step-simple.d.ts +12 -0
- package/dist/runner/step-simple.d.ts.map +1 -0
- package/dist/runner/step-simple.js +147 -0
- package/dist/runner/step-simple.js.map +1 -0
- package/dist/runner/steps.d.ts +13 -0
- package/dist/runner/steps.d.ts.map +1 -0
- package/dist/runner/steps.js +215 -0
- package/dist/runner/steps.js.map +1 -0
- package/dist/runner/types.d.ts +16 -0
- package/dist/runner/types.d.ts.map +1 -0
- package/dist/runner/types.js +2 -0
- package/dist/runner/types.js.map +1 -0
- package/dist/runner/typing.d.ts +6 -0
- package/dist/runner/typing.d.ts.map +1 -0
- package/dist/runner/typing.js +32 -0
- package/dist/runner/typing.js.map +1 -0
- package/dist/runner/utils.d.ts +19 -0
- package/dist/runner/utils.d.ts.map +1 -0
- package/dist/runner/utils.js +35 -0
- package/dist/runner/utils.js.map +1 -0
- package/dist/runner.d.ts +9 -68
- package/dist/runner.d.ts.map +1 -1
- package/dist/runner.js +8 -1040
- package/dist/runner.js.map +1 -1
- package/dist/schemas/config.d.ts +399 -0
- package/dist/schemas/config.d.ts.map +1 -0
- package/dist/schemas/config.js +56 -0
- package/dist/schemas/config.js.map +1 -0
- package/dist/schemas/index.d.ts +7 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/index.js +7 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/schemas/primitives.d.ts +220 -0
- package/dist/schemas/primitives.d.ts.map +1 -0
- package/dist/schemas/primitives.js +138 -0
- package/dist/schemas/primitives.js.map +1 -0
- package/dist/schemas/scenes.d.ts +2592 -0
- package/dist/schemas/scenes.d.ts.map +1 -0
- package/dist/schemas/scenes.js +135 -0
- package/dist/schemas/scenes.js.map +1 -0
- package/dist/schemas/selector.d.ts +24 -0
- package/dist/schemas/selector.d.ts.map +1 -0
- package/dist/schemas/selector.js +27 -0
- package/dist/schemas/selector.js.map +1 -0
- package/dist/schemas/steps.d.ts +755 -0
- package/dist/schemas/steps.d.ts.map +1 -0
- package/dist/schemas/steps.js +201 -0
- package/dist/schemas/steps.js.map +1 -0
- package/dist/schemas/transform.d.ts +3736 -0
- package/dist/schemas/transform.d.ts.map +1 -0
- package/dist/schemas/transform.js +40 -0
- package/dist/schemas/transform.js.map +1 -0
- package/dist/schemas.d.ts +1 -7337
- package/dist/schemas.d.ts.map +1 -1
- package/dist/schemas.js +1 -587
- package/dist/schemas.js.map +1 -1
- package/dist/script/tts.d.ts +8 -34
- package/dist/script/tts.d.ts.map +1 -1
- package/dist/script/tts.js +22 -354
- package/dist/script/tts.js.map +1 -1
- package/dist/stages/audio-mix.d.ts +8 -0
- package/dist/stages/audio-mix.d.ts.map +1 -0
- package/dist/stages/audio-mix.js +38 -0
- package/dist/stages/audio-mix.js.map +1 -0
- package/dist/stages/auth.d.ts +7 -0
- package/dist/stages/auth.d.ts.map +1 -0
- package/dist/stages/auth.js +18 -0
- package/dist/stages/auth.js.map +1 -0
- package/dist/stages/output.d.ts +7 -0
- package/dist/stages/output.d.ts.map +1 -0
- package/dist/stages/output.js +28 -0
- package/dist/stages/output.js.map +1 -0
- package/dist/stages/post-steps.d.ts +7 -0
- package/dist/stages/post-steps.d.ts.map +1 -0
- package/dist/stages/post-steps.js +27 -0
- package/dist/stages/post-steps.js.map +1 -0
- package/dist/stages/pre-steps.d.ts +7 -0
- package/dist/stages/pre-steps.d.ts.map +1 -0
- package/dist/stages/pre-steps.js +23 -0
- package/dist/stages/pre-steps.js.map +1 -0
- package/dist/stages/recording.d.ts +7 -0
- package/dist/stages/recording.d.ts.map +1 -0
- package/dist/stages/recording.js +39 -0
- package/dist/stages/recording.js.map +1 -0
- package/dist/stages/sync.d.ts +7 -0
- package/dist/stages/sync.d.ts.map +1 -0
- package/dist/stages/sync.js +54 -0
- package/dist/stages/sync.js.map +1 -0
- package/dist/stages/tts.d.ts +7 -0
- package/dist/stages/tts.d.ts.map +1 -0
- package/dist/stages/tts.js +87 -0
- package/dist/stages/tts.js.map +1 -0
- package/dist/video-handler.d.ts +2 -2
- package/dist/video-handler.d.ts.map +1 -1
- package/dist/video-handler.js +35 -52
- package/dist/video-handler.js.map +1 -1
- package/dist/voice/cache.d.ts +5 -0
- package/dist/voice/cache.d.ts.map +1 -0
- package/dist/voice/cache.js +29 -0
- package/dist/voice/cache.js.map +1 -0
- package/dist/voice/elevenlabs.d.ts +3 -0
- package/dist/voice/elevenlabs.d.ts.map +1 -0
- package/dist/voice/elevenlabs.js +36 -0
- package/dist/voice/elevenlabs.js.map +1 -0
- package/dist/voice/index.d.ts +5 -0
- package/dist/voice/index.d.ts.map +1 -0
- package/dist/voice/index.js +15 -0
- package/dist/voice/index.js.map +1 -0
- package/dist/voice/openai.d.ts +3 -0
- package/dist/voice/openai.d.ts.map +1 -0
- package/dist/voice/openai.js +21 -0
- package/dist/voice/openai.js.map +1 -0
- package/dist/voice/piper.d.ts +3 -0
- package/dist/voice/piper.d.ts.map +1 -0
- package/dist/voice/piper.js +92 -0
- package/dist/voice/piper.js.map +1 -0
- package/dist/voice/types.d.ts +17 -0
- package/dist/voice/types.d.ts.map +1 -0
- package/dist/voice/types.js +2 -0
- package/dist/voice/types.js.map +1 -0
- package/package.json +3 -2
- package/src/audio-processor.ts +15 -263
- package/src/browser/launcher.ts +66 -0
- package/src/browser/pool.ts +42 -0
- package/src/browser/types.ts +8 -0
- package/src/cli.ts +118 -61
- package/src/commands/types.ts +1 -0
- package/src/ffmpeg/utils.ts +391 -0
- package/src/index.ts +68 -181
- package/src/pipeline/context.ts +43 -0
- package/src/pipeline/orchestrator.ts +9 -0
- package/src/pipeline/types.ts +6 -0
- package/src/runner/assertions.ts +88 -0
- package/src/runner/cursor.ts +203 -0
- package/src/runner/index.ts +244 -0
- package/src/runner/motion.ts +181 -0
- package/src/runner/scene-tracking.ts +53 -0
- package/src/runner/selectors.ts +44 -0
- package/src/runner/step-simple.ts +197 -0
- package/src/runner/steps.ts +301 -0
- package/src/runner/types.ts +17 -0
- package/src/runner/typing.ts +47 -0
- package/src/runner/utils.ts +49 -0
- package/src/runner.ts +15 -1386
- package/src/schemas/config.ts +73 -0
- package/src/schemas/index.ts +108 -0
- package/src/schemas/primitives.ts +184 -0
- package/src/schemas/scenes.ts +165 -0
- package/src/schemas/selector.ts +32 -0
- package/src/schemas/steps.ts +229 -0
- package/src/schemas/transform.ts +80 -0
- package/src/schemas.ts +1 -732
- package/src/script/tts.ts +36 -441
- package/src/stages/audio-mix.ts +63 -0
- package/src/stages/auth.ts +19 -0
- package/src/stages/output.ts +41 -0
- package/src/stages/post-steps.ts +34 -0
- package/src/stages/pre-steps.ts +24 -0
- package/src/stages/recording.ts +48 -0
- package/src/stages/sync.ts +64 -0
- package/src/stages/tts.ts +103 -0
- package/src/video-handler.ts +48 -61
- package/src/voice/cache.ts +33 -0
- package/src/voice/elevenlabs.ts +46 -0
- package/src/voice/index.ts +21 -0
- package/src/voice/openai.ts +32 -0
- package/src/voice/piper.ts +106 -0
- package/src/voice/types.ts +15 -0
- package/dist/run.d.ts +0 -9
- package/dist/run.d.ts.map +0 -1
- package/dist/run.js +0 -29
- package/dist/run.js.map +0 -1
- package/src/run.ts +0 -44
|
@@ -1,37 +1,3 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
3
|
-
narrationManifest?: string;
|
|
4
|
-
narrationDelay?: number;
|
|
5
|
-
background?: string;
|
|
6
|
-
backgroundVolume?: number;
|
|
7
|
-
}
|
|
8
|
-
export interface NarrationPlacement {
|
|
9
|
-
sceneIndex: number;
|
|
10
|
-
narration: string;
|
|
11
|
-
clipPath: string;
|
|
12
|
-
startMs: number;
|
|
13
|
-
endMs: number;
|
|
14
|
-
}
|
|
15
|
-
interface MixAudioConfig extends AudioConfig {
|
|
16
|
-
narrationPlacements?: NarrationPlacement[];
|
|
17
|
-
}
|
|
18
|
-
export interface MergeOptions {
|
|
19
|
-
videoPath: string;
|
|
20
|
-
outputPath: string;
|
|
21
|
-
audio?: MixAudioConfig;
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Merge video with audio files using FFmpeg
|
|
25
|
-
*/
|
|
26
|
-
export declare function mergeAudioVideo(options: MergeOptions): Promise<string>;
|
|
27
|
-
export declare function buildFfmpegArgs(videoPath: string, outputPath: string, audio: AudioConfig): string[];
|
|
28
|
-
/**
|
|
29
|
-
* Check if FFmpeg is available
|
|
30
|
-
*/
|
|
31
|
-
export declare function isFfmpegAvailable(): Promise<boolean>;
|
|
32
|
-
/**
|
|
33
|
-
* Resolve audio paths relative to config file
|
|
34
|
-
*/
|
|
35
|
-
export declare function resolveAudioPaths(audio: AudioConfig | undefined, configDir: string): AudioConfig | undefined;
|
|
36
|
-
export {};
|
|
1
|
+
export { getFfmpegPath, getFfprobePath, runFFmpeg, runFfprobe, measureAudioDuration, wavToMp3, generateSilence, concatenateAudio, mergeAudioVideo, buildFfmpegArgs, isFfmpegAvailable, resolveAudioPaths, } from "./ffmpeg/utils.js";
|
|
2
|
+
export type { AudioConfig, NarrationPlacement, MergeOptions } from "./ffmpeg/utils.js";
|
|
37
3
|
//# sourceMappingURL=audio-processor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audio-processor.d.ts","sourceRoot":"","sources":["../src/audio-processor.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"audio-processor.d.ts","sourceRoot":"","sources":["../src/audio-processor.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,cAAc,EACd,SAAS,EACT,UAAU,EACV,oBAAoB,EACpB,QAAQ,EACR,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,WAAW,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC"}
|
package/dist/audio-processor.js
CHANGED
|
@@ -1,167 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
import { resolve } from "path";
|
|
3
|
-
// Import ffmpeg-static dynamically, fall back to system ffmpeg
|
|
4
|
-
async function getFfmpegPath() {
|
|
5
|
-
try {
|
|
6
|
-
const module = await import("ffmpeg-static");
|
|
7
|
-
const path = module.default;
|
|
8
|
-
if (path) {
|
|
9
|
-
// Verify the binary exists (ffmpeg-static may not ship it in prod)
|
|
10
|
-
const { accessSync } = await import("fs");
|
|
11
|
-
accessSync(path);
|
|
12
|
-
return path;
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
catch {
|
|
16
|
-
// ffmpeg-static not available or binary missing
|
|
17
|
-
}
|
|
18
|
-
// Fall back to system ffmpeg
|
|
19
|
-
return "ffmpeg";
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Merge video with audio files using FFmpeg
|
|
23
|
-
*/
|
|
24
|
-
export async function mergeAudioVideo(options) {
|
|
25
|
-
const { videoPath, outputPath, audio } = options;
|
|
26
|
-
const mixAudio = audio;
|
|
27
|
-
if (!audio || (!audio.narration && !audio.background && !mixAudio?.narrationPlacements?.length)) {
|
|
28
|
-
// No audio to process, just copy video
|
|
29
|
-
return videoPath;
|
|
30
|
-
}
|
|
31
|
-
const ffmpegPath = await getFfmpegPath();
|
|
32
|
-
if (!ffmpegPath) {
|
|
33
|
-
throw new Error("FFmpeg binary not found. Please ensure ffmpeg-static is installed correctly.");
|
|
34
|
-
}
|
|
35
|
-
// Change output to MP4 format when mixing audio (WebM doesn't support AAC)
|
|
36
|
-
const mp4OutputPath = outputPath.replace(/\.webm$/i, ".mp4");
|
|
37
|
-
const args = buildFfmpegArgs(videoPath, mp4OutputPath, audio);
|
|
38
|
-
return new Promise((resolve, reject) => {
|
|
39
|
-
const child = spawn(ffmpegPath, args, {
|
|
40
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
41
|
-
});
|
|
42
|
-
let stderr = "";
|
|
43
|
-
child.stderr.on("data", (data) => {
|
|
44
|
-
stderr += data.toString();
|
|
45
|
-
});
|
|
46
|
-
child.on("close", (code) => {
|
|
47
|
-
if (code === 0) {
|
|
48
|
-
resolve(mp4OutputPath);
|
|
49
|
-
}
|
|
50
|
-
else {
|
|
51
|
-
reject(new Error(`FFmpeg failed with code ${code}: ${stderr}`));
|
|
52
|
-
}
|
|
53
|
-
});
|
|
54
|
-
child.on("error", (err) => {
|
|
55
|
-
reject(new Error(`Failed to start FFmpeg: ${err.message}`));
|
|
56
|
-
});
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
export function buildFfmpegArgs(videoPath, outputPath, audio) {
|
|
60
|
-
const mixAudio = audio;
|
|
61
|
-
const args = [
|
|
62
|
-
"-y", // Overwrite output file
|
|
63
|
-
"-i",
|
|
64
|
-
videoPath, // Video input
|
|
65
|
-
];
|
|
66
|
-
let filterComplex = "";
|
|
67
|
-
const narrationDelay = audio.narrationDelay ?? 0;
|
|
68
|
-
if (mixAudio.narrationPlacements && mixAudio.narrationPlacements.length > 0) {
|
|
69
|
-
for (const placement of mixAudio.narrationPlacements) {
|
|
70
|
-
args.push("-i", placement.clipPath);
|
|
71
|
-
}
|
|
72
|
-
if (audio.background) {
|
|
73
|
-
args.push("-i", audio.background);
|
|
74
|
-
}
|
|
75
|
-
const narrationFilters = mixAudio.narrationPlacements.map((placement, index) => `[${index + 1}:a]adelay=${placement.startMs}|${placement.startMs},volume=1[n${index}]`);
|
|
76
|
-
const narrationInputs = mixAudio.narrationPlacements.map((_, index) => `[n${index}]`).join("");
|
|
77
|
-
const narrationMix = mixAudio.narrationPlacements.length === 1
|
|
78
|
-
? `${narrationInputs}anull[narr]`
|
|
79
|
-
: `${narrationInputs}amix=inputs=${mixAudio.narrationPlacements.length}:duration=longest:dropout_transition=0:normalize=0[narr]`;
|
|
80
|
-
if (audio.background) {
|
|
81
|
-
const backgroundInputIndex = mixAudio.narrationPlacements.length + 1;
|
|
82
|
-
const bgVolume = audio.backgroundVolume ?? 0.3;
|
|
83
|
-
filterComplex = `${narrationFilters.join(";")};${narrationMix};[${backgroundInputIndex}:a]volume=${bgVolume}[bg];[narr][bg]amix=inputs=2:duration=longest:dropout_transition=0:normalize=0[out]`;
|
|
84
|
-
args.push("-filter_complex", filterComplex, "-map", "0:v", "-map", "[out]");
|
|
85
|
-
}
|
|
86
|
-
else {
|
|
87
|
-
filterComplex = `${narrationFilters.join(";")};${narrationMix}`;
|
|
88
|
-
args.push("-filter_complex", filterComplex, "-map", "0:v", "-map", "[narr]");
|
|
89
|
-
}
|
|
90
|
-
args.push("-c:v", "libx264", "-preset", "fast", "-crf", "23", "-c:a", "aac", "-b:a", "192k", "-movflags", "+faststart", outputPath);
|
|
91
|
-
return args;
|
|
92
|
-
}
|
|
93
|
-
// Add narration if provided
|
|
94
|
-
if (audio.narration) {
|
|
95
|
-
args.push("-i", audio.narration);
|
|
96
|
-
}
|
|
97
|
-
// Add background music if provided
|
|
98
|
-
if (audio.background) {
|
|
99
|
-
args.push("-i", audio.background);
|
|
100
|
-
}
|
|
101
|
-
// Build filter complex for mixing
|
|
102
|
-
if (audio.narration && audio.background) {
|
|
103
|
-
// Both narration and background
|
|
104
|
-
const bgVolume = audio.backgroundVolume ?? 0.3;
|
|
105
|
-
if (narrationDelay > 0) {
|
|
106
|
-
// Delay the narration
|
|
107
|
-
const delayMs = narrationDelay;
|
|
108
|
-
filterComplex = `[1:a]adelay=${delayMs}|${delayMs}[delayed];[delayed]volume=1[narr];[2:a]volume=${bgVolume}[bg];[narr][bg]amix=inputs=2:duration=first:dropout_transition=0:normalize=0[out]`;
|
|
109
|
-
}
|
|
110
|
-
else {
|
|
111
|
-
filterComplex = `[1:a]volume=1[narr];[2:a]volume=${bgVolume}[bg];[narr][bg]amix=inputs=2:duration=first:dropout_transition=0:normalize=0[out]`;
|
|
112
|
-
}
|
|
113
|
-
args.push("-filter_complex", filterComplex, "-map", "0:v", // Video from first input
|
|
114
|
-
"-map", "[out]");
|
|
115
|
-
}
|
|
116
|
-
else if (audio.background) {
|
|
117
|
-
// Only background music
|
|
118
|
-
const bgVolume = audio.backgroundVolume ?? 0.3;
|
|
119
|
-
args.push("-filter_complex", `[1:a]volume=${bgVolume}[aout]`, "-map", "0:v", "-map", "[aout]");
|
|
120
|
-
}
|
|
121
|
-
else if (audio.narration && narrationDelay > 0) {
|
|
122
|
-
// Only narration with delay
|
|
123
|
-
const delayMs = narrationDelay;
|
|
124
|
-
args.push("-filter_complex", `[1:a]adelay=${delayMs}|${delayMs}[aout]`, "-map", "0:v", "-map", "[aout]");
|
|
125
|
-
}
|
|
126
|
-
// If only narration without delay, no filter needed - FFmpeg will auto-map
|
|
127
|
-
// Output settings - re-encode to H.264 for MP4 compatibility
|
|
128
|
-
args.push("-c:v", "libx264", // Re-encode video to H.264 (compatible with MP4)
|
|
129
|
-
"-preset", "fast", // Encoding speed/quality tradeoff
|
|
130
|
-
"-crf", "23", // Quality (lower = better, 23 is default)
|
|
131
|
-
"-c:a", "aac", // AAC audio codec
|
|
132
|
-
"-b:a", "192k", // Audio bitrate
|
|
133
|
-
"-movflags", "+faststart", // Enable web streaming
|
|
134
|
-
outputPath);
|
|
135
|
-
return args;
|
|
136
|
-
}
|
|
137
|
-
/**
|
|
138
|
-
* Check if FFmpeg is available
|
|
139
|
-
*/
|
|
140
|
-
export async function isFfmpegAvailable() {
|
|
141
|
-
const path = await getFfmpegPath();
|
|
142
|
-
return !!path;
|
|
143
|
-
}
|
|
144
|
-
/**
|
|
145
|
-
* Resolve audio paths relative to config file
|
|
146
|
-
*/
|
|
147
|
-
export function resolveAudioPaths(audio, configDir) {
|
|
148
|
-
if (!audio)
|
|
149
|
-
return undefined;
|
|
150
|
-
const resolved = {
|
|
151
|
-
backgroundVolume: audio.backgroundVolume ?? 0.3,
|
|
152
|
-
};
|
|
153
|
-
if (audio.narration) {
|
|
154
|
-
resolved.narration = resolve(configDir, audio.narration);
|
|
155
|
-
}
|
|
156
|
-
if (audio.narrationManifest) {
|
|
157
|
-
resolved.narrationManifest = resolve(configDir, audio.narrationManifest);
|
|
158
|
-
}
|
|
159
|
-
if (audio.narrationDelay !== undefined) {
|
|
160
|
-
resolved.narrationDelay = audio.narrationDelay;
|
|
161
|
-
}
|
|
162
|
-
if (audio.background) {
|
|
163
|
-
resolved.background = resolve(configDir, audio.background);
|
|
164
|
-
}
|
|
165
|
-
return resolved;
|
|
166
|
-
}
|
|
1
|
+
export { getFfmpegPath, getFfprobePath, runFFmpeg, runFfprobe, measureAudioDuration, wavToMp3, generateSilence, concatenateAudio, mergeAudioVideo, buildFfmpegArgs, isFfmpegAvailable, resolveAudioPaths, } from "./ffmpeg/utils.js";
|
|
167
2
|
//# sourceMappingURL=audio-processor.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audio-processor.js","sourceRoot":"","sources":["../src/audio-processor.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"audio-processor.js","sourceRoot":"","sources":["../src/audio-processor.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,cAAc,EACd,SAAS,EACT,UAAU,EACV,oBAAoB,EACpB,QAAQ,EACR,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { DemoReelConfig } from "../schemas.js";
|
|
2
|
+
import type { BrowserSession } from "./types.js";
|
|
3
|
+
export declare function launchBrowser(config: DemoReelConfig, headed?: boolean): Promise<BrowserSession>;
|
|
4
|
+
export declare function launchRecordingBrowser(config: DemoReelConfig, headed?: boolean): Promise<BrowserSession>;
|
|
5
|
+
export declare function closeSession(session: BrowserSession, saveSessionFn?: () => Promise<void>): Promise<string | null>;
|
|
6
|
+
//# sourceMappingURL=launcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"launcher.d.ts","sourceRoot":"","sources":["../../src/browser/launcher.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAIjD,wBAAsB,aAAa,CACjC,MAAM,EAAE,cAAc,EACtB,MAAM,GAAE,OAAe,GACtB,OAAO,CAAC,cAAc,CAAC,CAQzB;AAED,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,cAAc,EACtB,MAAM,GAAE,OAAe,GACtB,OAAO,CAAC,cAAc,CAAC,CAYzB;AAED,wBAAsB,YAAY,CAChC,OAAO,EAAE,cAAc,EACvB,aAAa,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAClC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAyBxB"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { chromium } from "playwright";
|
|
2
|
+
import { join } from "path";
|
|
3
|
+
const DEFAULT_TIMEOUT_MS = 5000;
|
|
4
|
+
export async function launchBrowser(config, headed = false) {
|
|
5
|
+
const browser = await chromium.launch({ headless: !headed });
|
|
6
|
+
const context = await browser.newContext({
|
|
7
|
+
viewport: config.video.resolution,
|
|
8
|
+
});
|
|
9
|
+
context.setDefaultTimeout(DEFAULT_TIMEOUT_MS);
|
|
10
|
+
const page = await context.newPage();
|
|
11
|
+
return { browser, context, page, isRecording: false };
|
|
12
|
+
}
|
|
13
|
+
export async function launchRecordingBrowser(config, headed = false) {
|
|
14
|
+
const browser = await chromium.launch({ headless: !headed });
|
|
15
|
+
const context = await browser.newContext({
|
|
16
|
+
viewport: config.video.resolution,
|
|
17
|
+
recordVideo: {
|
|
18
|
+
dir: join(process.cwd(), ".demo-reel-temp"),
|
|
19
|
+
size: config.video.resolution,
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
context.setDefaultTimeout(DEFAULT_TIMEOUT_MS);
|
|
23
|
+
const page = await context.newPage();
|
|
24
|
+
return { browser, context, page, isRecording: true };
|
|
25
|
+
}
|
|
26
|
+
export async function closeSession(session, saveSessionFn) {
|
|
27
|
+
const { page, context, browser, isRecording } = session;
|
|
28
|
+
await page.close();
|
|
29
|
+
let tempVideoPath = null;
|
|
30
|
+
if (isRecording) {
|
|
31
|
+
const video = page.video();
|
|
32
|
+
if (video) {
|
|
33
|
+
tempVideoPath = await video.path();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
if (saveSessionFn) {
|
|
37
|
+
await saveSessionFn();
|
|
38
|
+
}
|
|
39
|
+
await context.close();
|
|
40
|
+
await browser.close();
|
|
41
|
+
if (isRecording && !tempVideoPath) {
|
|
42
|
+
throw new Error("No video was recorded");
|
|
43
|
+
}
|
|
44
|
+
return tempVideoPath;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=launcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"launcher.js","sourceRoot":"","sources":["../../src/browser/launcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAI5B,MAAM,kBAAkB,GAAG,IAAI,CAAC;AAEhC,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,MAAsB,EACtB,MAAM,GAAY,KAAK;IAEvB,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;IAC7D,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC;QACvC,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,UAAU;KAClC,CAAC,CAAC;IACH,OAAO,CAAC,iBAAiB,CAAC,kBAAkB,CAAC,CAAC;IAC9C,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;IACrC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;AACxD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,MAAsB,EACtB,MAAM,GAAY,KAAK;IAEvB,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;IAC7D,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC;QACvC,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,UAAU;QACjC,WAAW,EAAE;YACX,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,iBAAiB,CAAC;YAC3C,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,UAAU;SAC9B;KACF,CAAC,CAAC;IACH,OAAO,CAAC,iBAAiB,CAAC,kBAAkB,CAAC,CAAC;IAC9C,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;IACrC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;AACvD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,OAAuB,EACvB,aAAmC;IAEnC,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC;IAExD,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;IAEnB,IAAI,aAAa,GAAkB,IAAI,CAAC;IACxC,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;QAC3B,IAAI,KAAK,EAAE,CAAC;YACV,aAAa,GAAG,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC;QACrC,CAAC;IACH,CAAC;IAED,IAAI,aAAa,EAAE,CAAC;QAClB,MAAM,aAAa,EAAE,CAAC;IACxB,CAAC;IAED,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;IACtB,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;IAEtB,IAAI,WAAW,IAAI,CAAC,aAAa,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;IAC3C,CAAC;IAED,OAAO,aAAa,CAAC;AACvB,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { DemoReelConfig } from "../schemas.js";
|
|
2
|
+
import type { BrowserSession } from "./types.js";
|
|
3
|
+
export interface AcquireOptions {
|
|
4
|
+
recording?: boolean;
|
|
5
|
+
headed?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare class BrowserPool {
|
|
8
|
+
private sessions;
|
|
9
|
+
acquire(config: DemoReelConfig, options?: AcquireOptions): Promise<BrowserSession>;
|
|
10
|
+
release(session: BrowserSession, saveSessionFn?: () => Promise<void>): Promise<string | null>;
|
|
11
|
+
releaseAll(): Promise<void>;
|
|
12
|
+
get active(): number;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=pool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pool.d.ts","sourceRoot":"","sources":["../../src/browser/pool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAGjD,MAAM,WAAW,cAAc;IAC7B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAwB;IAElC,OAAO,CAAC,MAAM,EAAE,cAAc,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,cAAc,CAAC,CAM3F;IAEK,OAAO,CACX,OAAO,EAAE,cAAc,EACvB,aAAa,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAClC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAIxB;IAEK,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAOhC;IAED,IAAI,MAAM,IAAI,MAAM,CAEnB;CACF"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { launchBrowser, launchRecordingBrowser, closeSession } from "./launcher.js";
|
|
2
|
+
export class BrowserPool {
|
|
3
|
+
sessions = [];
|
|
4
|
+
async acquire(config, options = {}) {
|
|
5
|
+
const session = await (options.recording
|
|
6
|
+
? launchRecordingBrowser(config, options.headed)
|
|
7
|
+
: launchBrowser(config, options.headed));
|
|
8
|
+
this.sessions.push(session);
|
|
9
|
+
return session;
|
|
10
|
+
}
|
|
11
|
+
async release(session, saveSessionFn) {
|
|
12
|
+
const idx = this.sessions.indexOf(session);
|
|
13
|
+
if (idx >= 0)
|
|
14
|
+
this.sessions.splice(idx, 1);
|
|
15
|
+
return closeSession(session, saveSessionFn);
|
|
16
|
+
}
|
|
17
|
+
async releaseAll() {
|
|
18
|
+
for (const session of this.sessions) {
|
|
19
|
+
try {
|
|
20
|
+
await closeSession(session);
|
|
21
|
+
}
|
|
22
|
+
catch { }
|
|
23
|
+
}
|
|
24
|
+
this.sessions = [];
|
|
25
|
+
}
|
|
26
|
+
get active() {
|
|
27
|
+
return this.sessions.length;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=pool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pool.js","sourceRoot":"","sources":["../../src/browser/pool.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,sBAAsB,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAOpF,MAAM,OAAO,WAAW;IACd,QAAQ,GAAqB,EAAE,CAAC;IAExC,KAAK,CAAC,OAAO,CAAC,MAAsB,EAAE,OAAO,GAAmB,EAAE;QAChE,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,SAAS;YACtC,CAAC,CAAC,sBAAsB,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC;YAChD,CAAC,CAAC,aAAa,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;QAC3C,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC5B,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,OAAO,CACX,OAAuB,EACvB,aAAmC;QAEnC,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAC3C,IAAI,GAAG,IAAI,CAAC;YAAE,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QAC3C,OAAO,YAAY,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;IAC9C,CAAC;IAED,KAAK,CAAC,UAAU;QACd,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACpC,IAAI,CAAC;gBACH,MAAM,YAAY,CAAC,OAAO,CAAC,CAAC;YAC9B,CAAC;YAAC,MAAM,CAAC,CAAA,CAAC;QACZ,CAAC;QACD,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;IACrB,CAAC;IAED,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;IAC9B,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/browser/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEhE,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,cAAc,CAAC;IACxB,IAAI,EAAE,IAAI,CAAC;IACX,WAAW,EAAE,OAAO,CAAC;CACtB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/browser/types.ts"],"names":[],"mappings":""}
|
package/dist/cli.d.ts
CHANGED
|
@@ -15,6 +15,7 @@ interface CliOptions {
|
|
|
15
15
|
scriptSpeed?: number;
|
|
16
16
|
scriptHints?: string[];
|
|
17
17
|
noCache?: boolean;
|
|
18
|
+
silent?: boolean;
|
|
18
19
|
resolution?: string;
|
|
19
20
|
format?: string;
|
|
20
21
|
track?: boolean;
|
|
@@ -24,8 +25,9 @@ interface CliOptions {
|
|
|
24
25
|
export declare function parseArgs(): {
|
|
25
26
|
scenario?: string;
|
|
26
27
|
options: CliOptions;
|
|
28
|
+
unknownFlags: string[];
|
|
27
29
|
};
|
|
28
|
-
export declare function showHelp(): void
|
|
30
|
+
export declare function showHelp(): Promise<void>;
|
|
29
31
|
export declare function runCli(): Promise<number>;
|
|
30
32
|
export declare function main(): Promise<void>;
|
|
31
33
|
export {};
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AA2BA,UAAU,UAAU;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,GAAG,EAAE,OAAO,CAAC;IACb,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAEhB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAiID,wBAAgB,SAAS,IAAI;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,UAAU,CAAC;IAAC,YAAY,EAAE,MAAM,EAAE,CAAA;CAAE,CAiH9F;AAyDD,wBAAsB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAG9C;AAED,wBAAsB,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,CAmH9C;AAED,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAE1C"}
|