mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
feat(tools): 2.0 phase 5 wave 3a - video depth (22 tools) (#221)
This commit is contained in:
@@ -37,6 +37,40 @@ export interface MediaRunResult {
|
||||
durationS: number | null;
|
||||
}
|
||||
|
||||
/** Stages every ctx input into scratch (in-<i>-<sanitized>) and returns the paths. */
|
||||
export async function stageMediaInputs(ctx: ToolProcessCtxV2): Promise<string[]> {
|
||||
const dir = join(ctx.scratchDir, "media");
|
||||
await mkdir(dir, { recursive: true });
|
||||
const paths: string[] = [];
|
||||
for (let i = 0; i < ctx.inputs.length; i++) {
|
||||
const safe = ctx.inputs[i].filename.replace(/[^A-Za-z0-9._-]/g, "_");
|
||||
const p = join(dir, `in-${i}-${safe}`);
|
||||
await writeFile(p, ctx.inputs[i].buffer);
|
||||
paths.push(p);
|
||||
}
|
||||
return paths;
|
||||
}
|
||||
|
||||
/** Progress-mapped runFfmpeg (5..95%) against a known duration; 30 min default timeout. */
|
||||
export async function runFfmpegWithProgress(
|
||||
ctx: ToolProcessCtxV2,
|
||||
args: string[],
|
||||
durationS: number | null,
|
||||
opts: { timeoutMs?: number } = {},
|
||||
): Promise<void> {
|
||||
ctx.report(5, "Preparing");
|
||||
await runFfmpeg(args, {
|
||||
signal: ctx.signal,
|
||||
timeoutMs: opts.timeoutMs ?? 30 * 60_000,
|
||||
onProgress: (p) => {
|
||||
if (p.outTimeMs !== null && durationS) {
|
||||
const pct = Math.min(95, 5 + Math.round((p.outTimeMs / (durationS * 1000)) * 90));
|
||||
ctx.report(pct, "Processing");
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Stages the primary input in the scratch dir, probes it, runs ffmpeg with
|
||||
* progress mapped onto ctx.report (5..95%), and returns the output path for
|
||||
@@ -54,16 +88,11 @@ export async function runMediaTool(
|
||||
await writeFile(inPath, ctx.inputs[0].buffer);
|
||||
const info = await probeMedia(inPath);
|
||||
const outPath = join(dir, outName);
|
||||
ctx.report(5, "Preparing");
|
||||
await runFfmpeg(argsFor(inPath, outPath, { durationS: info.durationS }), {
|
||||
signal: ctx.signal,
|
||||
timeoutMs: opts.timeoutMs ?? 30 * 60_000,
|
||||
onProgress: (p) => {
|
||||
if (p.outTimeMs !== null && info.durationS) {
|
||||
const pct = Math.min(95, 5 + Math.round((p.outTimeMs / (info.durationS * 1000)) * 90));
|
||||
ctx.report(pct, "Processing");
|
||||
}
|
||||
},
|
||||
});
|
||||
await runFfmpegWithProgress(
|
||||
ctx,
|
||||
argsFor(inPath, outPath, { durationS: info.durationS }),
|
||||
info.durationS,
|
||||
opts,
|
||||
);
|
||||
return { outPath, durationS: info.durationS };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user