Initial commit: PodcastYes — AI podcast platform
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
import { spawn } from "node:child_process";
|
||||
|
||||
const FFMPEG = process.env.FFMPEG_PATH ?? "ffmpeg";
|
||||
const FFPROBE = process.env.FFPROBE_PATH ?? "ffprobe";
|
||||
|
||||
/** Run ffmpeg with the given args; rejects with the tail of stderr on non-zero exit. */
|
||||
export function runFfmpeg(args: string[]): Promise<void> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const proc = spawn(FFMPEG, args, { stdio: ["ignore", "ignore", "pipe"] });
|
||||
let stderr = "";
|
||||
proc.stderr.on("data", (d) => {
|
||||
stderr += d.toString();
|
||||
});
|
||||
proc.on("error", (err) =>
|
||||
reject(new Error(`Failed to spawn ffmpeg (${FFMPEG}): ${err.message}`))
|
||||
);
|
||||
proc.on("close", (code) =>
|
||||
code === 0 ? resolve() : reject(new Error(`ffmpeg exited ${code}: ${stderr.slice(-600)}`))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/** Probe an audio file's duration in whole seconds, or null if ffprobe is unavailable. */
|
||||
export function ffprobeDuration(file: string): Promise<number | null> {
|
||||
return new Promise((resolve) => {
|
||||
const proc = spawn(FFPROBE, [
|
||||
"-v",
|
||||
"error",
|
||||
"-show_entries",
|
||||
"format=duration",
|
||||
"-of",
|
||||
"default=noprint_wrappers=1:nokey=1",
|
||||
file,
|
||||
]);
|
||||
let out = "";
|
||||
proc.stdout.on("data", (d) => {
|
||||
out += d.toString();
|
||||
});
|
||||
proc.on("error", () => resolve(null));
|
||||
proc.on("close", () => {
|
||||
const n = parseFloat(out.trim());
|
||||
resolve(Number.isFinite(n) ? Math.round(n) : null);
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user