ffmpeg-stream
Version:
Node bindings to ffmpeg command, exposing stream based API
224 lines (223 loc) • 7.26 kB
TypeScript
/**
* A class which wraps a FFmpeg process.
*
* @example
*
* ```js
* import { Converter } from "ffmpeg-stream"
*
* const converter = new Converter()
*
* converter.createInputFromFile("input.mp4")
* converter.createOutputToFile("output.webm")
*
* await converter.run()
* ```
*/
export class Converter {
/**
* Initializes the converter.
*
* Remember to call {@link Converter.run} to actually start the FFmpeg process.
*
* @param {string} [ffmpegPath] Path to the FFmpeg executable. (default: `"ffmpeg"`)
*/
constructor(ffmpegPath?: string | undefined);
/**
* @private
*/
private fdCount;
/**
* @private
* @readonly
* @type {ConverterPipe[]}
*/
private readonly pipes;
/**
* @private
* @type {import("node:child_process").ChildProcess | undefined}
*/
private process;
/**
* @private
*/
private killed;
/** @private */
private ffmpegPath;
/**
* Defines an FFmpeg input file.
*
* This builds a command like the one you would normally use in the terminal.
*
* @param {string} file Path to the input file.
* @param {ConverterPipeOptions} [options] FFmpeg options for this input.
*
* @example
*
* ```js
* import { Converter } from "ffmpeg-stream"
*
* const converter = new Converter()
*
* converter.createInputFromFile("input.mp4", { r: 30 })
* // ffmpeg -r 30 -i input.mp4 ...
*
* await converter.run()
* ```
*/
createInputFromFile(file: string, options?: ConverterPipeOptions | undefined): void;
/**
* Defines an FFmpeg output file.
*
* This builds a command like the one you would normally use in the terminal.
*
* @param {string} file Path to the output file.
* @param {ConverterPipeOptions} [options] FFmpeg options for this output.
*
* @example
*
* ```js
* import { Converter } from "ffmpeg-stream"
*
* const converter = new Converter()
*
* converter.createOutputToFile("output.mp4", { vcodec: "libx264" })
* // ffmpeg ... -vcodec libx264 output.mp4
*
* await converter.run()
* ```
*/
createOutputToFile(file: string, options?: ConverterPipeOptions | undefined): void;
/**
* Defines an FFmpeg input stream.
*
* Internally, it adds a special `pipe:<number>` input argument to the FFmpeg command.
*
* Remember to specify the [`f` option](https://ffmpeg.org/ffmpeg.html#Main-options),
* which specifies the format of the input data.
*
* @param {ConverterPipeOptions} options FFmpeg options for this input.
* @returns {import("node:stream").Writable} A stream which will be written to the FFmpeg process' stdio.
*
* @example
*
* ```js
* import { createReadStream } from "node:fs"
* import { Converter } from "ffmpeg-stream"
*
* const converter = new Converter()
*
* createReadStream("input.mp4").pipe(
* converter.createInputStream({ f: "mp4" }),
* )
*
* await converter.run()
* ```
*/
createInputStream(options: ConverterPipeOptions): import("node:stream").Writable;
/**
* Defines an FFmpeg output stream.
*
* Internally, it adds a special `pipe:<number>` output argument to the FFmpeg command.
*
* Remember to specify the [`f` option](https://ffmpeg.org/ffmpeg.html#Main-options),
* which specifies the format of the output data.
*
* @param {ConverterPipeOptions} options FFmpeg options for this output.
* @returns {import("node:stream").Readable} A stream which will be read from the FFmpeg process' stdio.
*
* @example
*
* ```js
* import { createWriteStream } from "node:fs"
* import { Converter } from "ffmpeg-stream"
*
* const converter = new Converter()
*
* converter.createOutputStream({ f: "mp4" })
* .pipe(createWriteStream("output.mp4"))
*
* await converter.run()
* ```
*/
createOutputStream(options: ConverterPipeOptions): import("node:stream").Readable;
/**
* Defines an FFmpeg input stream from a temporary file.
*
* Creates a temporary file that you can write to and instructs FFmpeg to read from it.
* Note that the actual conversion process will not start until the file is fully written.
*
* Use this method if the format you want to read doesn't support non-seekable input.
*
* @param {ConverterPipeOptions} options FFmpeg options for this input.
* @returns {import("node:stream").Writable} A stream which will be written to the temporary file.
*/
createBufferedInputStream(options: ConverterPipeOptions): import("node:stream").Writable;
/**
* Defines an FFmpeg output stream to a temporary file.
*
* Creates a temporary file that you can read from and instructs FFmpeg to write to it.
* Note that you will be able to read from the file only after the conversion process is finished.
*
* Use this method if the format you want to write doesn't support non-seekable output.
*
* @param {ConverterPipeOptions} options FFmpeg options for this output.
* @returns {import("node:stream").Readable} A stream which will be read from the temporary file.
*/
createBufferedOutputStream(options: ConverterPipeOptions): import("node:stream").Readable;
/**
* Starts the conversion process.
*
* You can use {@link Converter.kill} to cancel the conversion.
*
* @returns {Promise<void>} Promise which resolves on normal exit or kill, but rejects on ffmpeg error.
*/
run(): Promise<void>;
/**
* Stops the conversion process.
*/
kill(): void;
/**
* @private
* @returns {number}
*/
private getUniqueFd;
/**
* Returns stdio pipes which can be passed to {@link spawn}.
* @private
* @returns {Array<"ignore" | "pipe">}
*/
private getStdioArg;
/**
* Returns arguments which can be passed to {@link spawn}.
* @private
* @returns {string[]}
*/
private getSpawnArgs;
/**
* @private
*/
private handleProcess;
}
/**
* Options object for a single input or output of a {@link Converter}.
*
* These are the same options that you normally pass to the ffmpeg command in the terminal.
* Documentation for individual options can be found in the [ffmpeg docs](https://ffmpeg.org/ffmpeg.html#Main-options).
*
* To specify a boolean option, set it to `true`.
* To specify an option multiple times, use an array.
* Options with nullish or `false` values are ignored.
*/
export type ConverterPipeOptions = Record<string, string | number | boolean | Array<string | null | undefined> | null | undefined>;
/**
* Data about a single input or output of a {@link Converter}.
*/
export type ConverterPipe = {
type: "input" | "output";
options: ConverterPipeOptions;
file: string;
onBegin?: (() => Promise<void>) | undefined;
onSpawn?: ((process: import("node:child_process").ChildProcess) => void) | undefined;
onFinish?: (() => Promise<void>) | undefined;
};