diff --git a/src/modules/stream/cut.js b/src/modules/stream/cut.js index 5328f846..b60da766 100644 --- a/src/modules/stream/cut.js +++ b/src/modules/stream/cut.js @@ -1,5 +1,5 @@ import { strict as assert } from 'node:assert'; -import { spawn } from 'node:child_process'; +import { spawn } from './shared.js'; import { path as ffprobe } from 'ffprobe-static'; function mapFormat(format) { diff --git a/src/modules/stream/shared.js b/src/modules/stream/shared.js new file mode 100644 index 00000000..3e911eee --- /dev/null +++ b/src/modules/stream/shared.js @@ -0,0 +1,38 @@ +import { spawn as _node_spawn } from 'child_process' + +export function killProcess(p) { + // ask the process to terminate itself gracefully + p?.kill('SIGTERM'); + setTimeout(() => { + if (p?.exitCode === null) + // brutally murder the process if it didn't quit + p?.kill('SIGKILL'); + }, 5000); +} + +export function pipe(from, to, done) { + from.on('error', done) + .on('close', done); + + to.on('error', done) + .on('close', done); + + from.pipe(to); +} + +export function wrapCommand(command, args = []) { + if (process.env.PROCESSING_PRIORITY && process.platform !== "win32") { + return ['nice', ['-n', process.env.PROCESSING_PRIORITY, command, ...args]] + } + + return [command, args] +} + +export function spawn(command, args, opts) { + opts = { + ...opts, + windowsHide: true + }; + + return _node_spawn(...wrapCommand(command, args), opts); +} \ No newline at end of file diff --git a/src/modules/stream/types.js b/src/modules/stream/types.js index cdfb4a05..d07ac3d2 100644 --- a/src/modules/stream/types.js +++ b/src/modules/stream/types.js @@ -1,6 +1,6 @@ -import { spawn } from "child_process"; import ffmpeg from "ffmpeg-static"; import { ffmpegArgs, genericUserAgent } from "../config.js"; +import { spawn, pipe, killProcess } from "./shared.js"; import { metadataManager } from "../sub/utils.js"; import { request } from "undici"; import { create as contentDisposition } from "content-disposition-header"; @@ -15,33 +15,6 @@ function closeResponse(res) { return res.destroy(); } -function killProcess(p) { - // ask the process to terminate itself gracefully - p?.kill('SIGTERM'); - setTimeout(() => { - if (p?.exitCode === null) - // brutally murder the process if it didn't quit - p?.kill('SIGKILL'); - }, 5000); -} - -function pipe(from, to, done) { - from.on('error', done) - .on('close', done); - - to.on('error', done) - .on('close', done); - - from.pipe(to); -} - -function getCommand(args) { - if (process.env.PROCESSING_PRIORITY && process.platform !== "win32") { - return ['nice', ['-n', process.env.PROCESSING_PRIORITY, ffmpeg, ...args]] - } - return [ffmpeg, args] -} - export async function streamDefault(streamInfo, res) { const abortController = new AbortController(); const shutdown = () => (closeRequest(abortController), closeResponse(res)); @@ -98,8 +71,7 @@ export async function streamLiveRender(streamInfo, res) { } args.push('-f', format, 'pipe:4'); - process = spawn(...getCommand(args), { - windowsHide: true, + process = spawn(ffmpeg, args, { stdio: [ 'inherit', 'inherit', 'inherit', 'pipe', 'pipe' @@ -140,18 +112,18 @@ export function streamAudioOnly(streamInfo, res) { ) if (streamInfo.metadata) { - args = args.concat(metadataManager(streamInfo.metadata)) + args.push(...metadataManager(streamInfo.metadata)) } - let arg = streamInfo.copy ? ffmpegArgs["copy"] : ffmpegArgs["audio"]; - args = args.concat(arg); + + args.push(...ffmpegArgs[streamInfo.copy ? "copy" : "audio"]); if (ffmpegArgs[streamInfo.audioFormat]) { - args = args.concat(ffmpegArgs[streamInfo.audioFormat]) + args.push(...ffmpegArgs[streamInfo.audioFormat]); } + args.push('-f', streamInfo.audioFormat === "m4a" ? "ipod" : streamInfo.audioFormat, 'pipe:3'); - process = spawn(...getCommand(args), { - windowsHide: true, + process = spawn(ffmpeg, args, { stdio: [ 'inherit', 'inherit', 'inherit', 'pipe' @@ -198,8 +170,7 @@ export function streamVideoOnly(streamInfo, res) { } args.push('-f', format, 'pipe:3'); - process = spawn(...getCommand(args), { - windowsHide: true, + process = spawn(ffmpeg, args, { stdio: [ 'inherit', 'inherit', 'inherit', 'pipe' @@ -235,8 +206,7 @@ export function convertToGif(streamInfo, res) { args = args.concat(ffmpegArgs["gif"]); args.push('-f', "gif", 'pipe:3'); - process = spawn(...getCommand(args), { - windowsHide: true, + process = spawn(ffmpeg, args, { stdio: [ 'inherit', 'inherit', 'inherit', 'pipe'