289 lines
7.7 KiB
TypeScript
289 lines
7.7 KiB
TypeScript
import type * as interfaces from './interfaces.js';
|
|
/**
|
|
* Input source for FfmpegCommand
|
|
* Supports file paths, memory buffers, and Web Streams
|
|
*/
|
|
export type TFfmpegInput = string | Buffer | Uint8Array | ReadableStream<Uint8Array>;
|
|
/**
|
|
* Output destination for FfmpegCommand
|
|
*/
|
|
export type TFfmpegOutput = string | 'buffer' | 'stream' | WritableStream<Uint8Array>;
|
|
/**
|
|
* Input options when using Buffer or Stream
|
|
*/
|
|
export interface IInputOptions {
|
|
/** Input format (required for buffer/stream input) */
|
|
format?: interfaces.TOutputFormat;
|
|
/** Input duration hint for progress calculation */
|
|
duration?: number;
|
|
}
|
|
/**
|
|
* Result of running an FfmpegCommand
|
|
*/
|
|
export interface IFfmpegResult {
|
|
/** Output buffer (when outputting to buffer) */
|
|
buffer?: Buffer;
|
|
/** Output stream (when outputting to stream) */
|
|
stream?: ReadableStream<Uint8Array>;
|
|
/** Path to output file (when outputting to file) */
|
|
outputPath?: string;
|
|
/** Duration of processing in ms */
|
|
processingTime: number;
|
|
}
|
|
/**
|
|
* Progress callback type for FfmpegCommand
|
|
*/
|
|
export type TFfmpegProgressCallback = (progress: interfaces.IProgressInfo) => void;
|
|
/**
|
|
* Modern fluent builder API for ffmpeg commands
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // File to file
|
|
* await ffmpeg.create()
|
|
* .input('/path/to/input.mp4')
|
|
* .videoCodec('libx264')
|
|
* .audioBitrate('128k')
|
|
* .output('/path/to/output.mp4')
|
|
* .run();
|
|
*
|
|
* // Buffer to buffer
|
|
* const outputBuffer = await ffmpeg.create()
|
|
* .input(inputBuffer, { format: 'mp4' })
|
|
* .videoCodec('libx264')
|
|
* .toBuffer('webm');
|
|
*
|
|
* // With progress
|
|
* await ffmpeg.create()
|
|
* .input('/path/to/input.mp4')
|
|
* .videoCodec('libx264')
|
|
* .onProgress(p => console.log(`${p.percent}%`))
|
|
* .output('/path/to/output.mp4')
|
|
* .run();
|
|
* ```
|
|
*/
|
|
export declare class FfmpegCommand {
|
|
private ffmpegPath;
|
|
private ffprobePath;
|
|
private inputSource;
|
|
private inputOpts;
|
|
private customInputArgs;
|
|
private outputDest;
|
|
private outputFormat;
|
|
private customOutputArgs;
|
|
private _videoCodec;
|
|
private _videoBitrate;
|
|
private _width;
|
|
private _height;
|
|
private _fps;
|
|
private _crf;
|
|
private _preset;
|
|
private _noVideo;
|
|
private _audioCodec;
|
|
private _audioBitrate;
|
|
private _sampleRate;
|
|
private _audioChannels;
|
|
private _noAudio;
|
|
private _startTime;
|
|
private _duration;
|
|
private videoFilters;
|
|
private audioFilters;
|
|
private _complexFilter;
|
|
private extraInputArgs;
|
|
private extraOutputArgs;
|
|
private progressCallback;
|
|
private _overwrite;
|
|
constructor(ffmpegPath: string, ffprobePath: string);
|
|
/**
|
|
* Set the input source
|
|
* @param source - File path, Buffer, or Readable stream
|
|
* @param options - Input options (format required for buffer/stream)
|
|
*/
|
|
input(source: TFfmpegInput, options?: IInputOptions): this;
|
|
/**
|
|
* Seek to position before input (fast seek)
|
|
* @param time - Time in seconds or timecode string
|
|
*/
|
|
seekInput(time: number | string): this;
|
|
/**
|
|
* Add custom input arguments
|
|
*/
|
|
inputArgs(...args: string[]): this;
|
|
/**
|
|
* Set video codec
|
|
*/
|
|
videoCodec(codec: interfaces.TVideoCodec): this;
|
|
/**
|
|
* Set video bitrate
|
|
* @param bitrate - e.g., '1M', '2000k'
|
|
*/
|
|
videoBitrate(bitrate: string): this;
|
|
/**
|
|
* Set output dimensions
|
|
* @param width - Width in pixels (-1 for auto)
|
|
* @param height - Height in pixels (-1 for auto)
|
|
*/
|
|
size(width: number, height?: number): this;
|
|
/**
|
|
* Set frame rate
|
|
*/
|
|
fps(rate: number): this;
|
|
/**
|
|
* Set Constant Rate Factor (quality)
|
|
* @param value - 0-51, lower is better quality
|
|
*/
|
|
crf(value: number): this;
|
|
/**
|
|
* Set encoding preset
|
|
*/
|
|
preset(value: interfaces.TPreset): this;
|
|
/**
|
|
* Remove video stream
|
|
*/
|
|
noVideo(): this;
|
|
/**
|
|
* Add a video filter
|
|
* @param filter - Filter string (e.g., 'scale=1920:1080', 'hflip')
|
|
*/
|
|
videoFilter(filter: string): this;
|
|
/**
|
|
* Scale video
|
|
* @param width - Width (-1 or -2 for auto)
|
|
* @param height - Height (-1 or -2 for auto)
|
|
*/
|
|
scale(width: number | string, height: number | string): this;
|
|
/**
|
|
* Crop video
|
|
*/
|
|
crop(width: number, height: number, x?: number, y?: number): this;
|
|
/**
|
|
* Rotate video
|
|
* @param angle - Rotation in radians or 'PI/2', 'PI', etc.
|
|
*/
|
|
rotate(angle: number | string): this;
|
|
/**
|
|
* Flip video horizontally
|
|
*/
|
|
flipHorizontal(): this;
|
|
/**
|
|
* Flip video vertically
|
|
*/
|
|
flipVertical(): this;
|
|
/**
|
|
* Add padding to video
|
|
*/
|
|
pad(width: number, height: number, x?: number, y?: number, color?: string): this;
|
|
/**
|
|
* Set audio codec
|
|
*/
|
|
audioCodec(codec: interfaces.TAudioCodec): this;
|
|
/**
|
|
* Set audio bitrate
|
|
* @param bitrate - e.g., '128k', '320k'
|
|
*/
|
|
audioBitrate(bitrate: string): this;
|
|
/**
|
|
* Set audio sample rate
|
|
* @param rate - Sample rate in Hz (e.g., 44100, 48000)
|
|
*/
|
|
sampleRate(rate: number): this;
|
|
/**
|
|
* Set number of audio channels
|
|
* @param channels - 1 for mono, 2 for stereo
|
|
*/
|
|
audioChannels(channels: number): this;
|
|
/**
|
|
* Remove audio stream
|
|
*/
|
|
noAudio(): this;
|
|
/**
|
|
* Add an audio filter
|
|
* @param filter - Filter string (e.g., 'volume=2', 'aecho=0.8:0.88:60:0.4')
|
|
*/
|
|
audioFilter(filter: string): this;
|
|
/**
|
|
* Set audio volume
|
|
* @param level - Volume multiplier (e.g., 2 for double, 0.5 for half)
|
|
*/
|
|
volume(level: number): this;
|
|
/**
|
|
* Normalize audio
|
|
*/
|
|
normalize(): this;
|
|
/**
|
|
* Set start time (seek)
|
|
* @param time - Time in seconds or timecode string
|
|
*/
|
|
seek(time: number | string): this;
|
|
/**
|
|
* Set output duration
|
|
* @param time - Duration in seconds or timecode string
|
|
*/
|
|
duration(time: number | string): this;
|
|
/**
|
|
* Set both start and end time
|
|
*/
|
|
trim(start: number | string, end: number | string): this;
|
|
/**
|
|
* Set a complex filter graph
|
|
* @param filterGraph - Complex filter string
|
|
*/
|
|
complexFilter(filterGraph: string): this;
|
|
/**
|
|
* Set output format
|
|
*/
|
|
format(fmt: interfaces.TOutputFormat): this;
|
|
/**
|
|
* Set output destination (file path)
|
|
*/
|
|
output(dest: string): this;
|
|
/**
|
|
* Add custom output arguments
|
|
*/
|
|
outputArgs(...args: string[]): this;
|
|
/**
|
|
* Set overwrite flag
|
|
*/
|
|
overwrite(value?: boolean): this;
|
|
/**
|
|
* Set progress callback
|
|
*/
|
|
onProgress(callback: TFfmpegProgressCallback): this;
|
|
/**
|
|
* Run the command and output to file
|
|
*/
|
|
run(): Promise<IFfmpegResult>;
|
|
/**
|
|
* Run the command and return output as Buffer
|
|
* @param format - Output format
|
|
*/
|
|
toBuffer(format?: interfaces.TOutputFormat): Promise<Buffer>;
|
|
/**
|
|
* Run the command and return output as Web ReadableStream
|
|
* @param format - Output format
|
|
*/
|
|
toStream(format?: interfaces.TOutputFormat): ReadableStream<Uint8Array>;
|
|
/**
|
|
* Pipe output to a Web WritableStream
|
|
* @param writable - Web WritableStream
|
|
* @param format - Output format
|
|
*/
|
|
pipe(writable: WritableStream<Uint8Array>, format?: interfaces.TOutputFormat): Promise<void>;
|
|
/**
|
|
* Get the ffmpeg arguments that would be used (for debugging)
|
|
*/
|
|
getArgs(outputPath?: string): string[];
|
|
private buildArgs;
|
|
private execute;
|
|
private executeToBuffer;
|
|
private executeToNodeStream;
|
|
private parseProgress;
|
|
private getInputDuration;
|
|
private runProbe;
|
|
private formatTime;
|
|
private isNodeStream;
|
|
private isWebReadableStream;
|
|
private isMemoryInput;
|
|
private pipeInputToProcess;
|
|
}
|