(args: string[])
| 12 | } |
| 13 | |
| 14 | function runFfmpeg(args: string[]): Promise<void> { |
| 15 | const ffmpeg = getFfmpegPath(); |
| 16 | |
| 17 | return new Promise((resolve, reject) => { |
| 18 | const proc = spawn(ffmpeg, args, { stdio: ["ignore", "ignore", "pipe"] }); |
| 19 | |
| 20 | let stderr = ""; |
| 21 | |
| 22 | proc.stderr?.on("data", (data: Buffer) => { |
| 23 | stderr += data.toString(); |
| 24 | }); |
| 25 | |
| 26 | proc.on("error", (err: Error) => { |
| 27 | reject(new Error(`Video conversion failed: ${err.message}`)); |
| 28 | }); |
| 29 | |
| 30 | proc.on("close", (code: number | null) => { |
| 31 | if (code === 0) { |
| 32 | resolve(); |
| 33 | return; |
| 34 | } |
| 35 | |
| 36 | reject(new Error(`Video conversion failed with code ${code}: ${stderr}`)); |
| 37 | }); |
| 38 | }); |
| 39 | } |
| 40 | |
| 41 | function isHlsUrl(url: string): boolean { |
| 42 | return (url.split("?")[0] ?? "").toLowerCase().endsWith(".m3u8"); |
no test coverage detected