2022-07-23 10:36:03 +05:00
|
|
|
import { FFmpeg } from "prism-media";
|
|
|
|
import type { Duplex, Readable } from "stream";
|
|
|
|
|
|
|
|
export interface FFmpegStreamOptions {
|
2023-03-01 23:48:04 +05:00
|
|
|
fmt?: string;
|
|
|
|
encoderArgs?: string[];
|
|
|
|
seek?: number;
|
|
|
|
skip?: boolean;
|
2022-07-23 10:36:03 +05:00
|
|
|
}
|
|
|
|
|
|
|
|
export function FFMPEG_ARGS_STRING(stream: string, fmt?: string) {
|
2023-03-01 23:48:04 +05:00
|
|
|
// prettier-ignore
|
|
|
|
return [
|
2022-07-23 10:36:03 +05:00
|
|
|
"-reconnect", "1",
|
|
|
|
"-reconnect_streamed", "1",
|
|
|
|
"-reconnect_delay_max", "5",
|
|
|
|
"-i", stream,
|
|
|
|
"-analyzeduration", "0",
|
|
|
|
"-loglevel", "0",
|
|
|
|
"-f", `${typeof fmt === "string" ? fmt : "s16le"}`,
|
|
|
|
"-ar", "48000",
|
|
|
|
"-ac", "2"
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
export function FFMPEG_ARGS_PIPED(fmt?: string) {
|
2023-03-01 23:48:04 +05:00
|
|
|
// prettier-ignore
|
|
|
|
return [
|
2022-07-23 10:36:03 +05:00
|
|
|
"-analyzeduration", "0",
|
|
|
|
"-loglevel", "0",
|
|
|
|
"-f", `${typeof fmt === "string" ? fmt : "s16le"}`,
|
|
|
|
"-ar", "48000",
|
|
|
|
"-ac", "2"
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Creates FFmpeg stream
|
|
|
|
* @param stream The source stream
|
|
|
|
* @param options FFmpeg stream options
|
|
|
|
*/
|
|
|
|
export function createFFmpegStream(stream: Readable | Duplex | string, options?: FFmpegStreamOptions) {
|
2023-03-01 23:48:04 +05:00
|
|
|
if (options.skip && typeof stream !== "string") return stream;
|
|
|
|
options ??= {};
|
|
|
|
const args = typeof stream === "string" ? FFMPEG_ARGS_STRING(stream, options.fmt) : FFMPEG_ARGS_PIPED(options.fmt);
|
2022-07-23 10:36:03 +05:00
|
|
|
|
2023-03-01 23:48:04 +05:00
|
|
|
if (!Number.isNaN(options.seek)) args.unshift("-ss", String(options.seek));
|
|
|
|
if (Array.isArray(options.encoderArgs)) args.push(...options.encoderArgs);
|
2022-07-23 10:36:03 +05:00
|
|
|
|
2023-03-01 23:48:04 +05:00
|
|
|
const transcoder = new FFmpeg({ shell: false, args });
|
|
|
|
transcoder.on("close", () => transcoder.destroy());
|
2022-07-23 10:36:03 +05:00
|
|
|
|
2023-03-01 23:48:04 +05:00
|
|
|
if (typeof stream !== "string") {
|
|
|
|
stream.on("error", () => transcoder.destroy());
|
|
|
|
stream.pipe(transcoder);
|
|
|
|
}
|
2022-07-23 10:36:03 +05:00
|
|
|
|
2023-03-01 23:48:04 +05:00
|
|
|
return transcoder;
|
2022-07-23 10:36:03 +05:00
|
|
|
}
|