Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 5x 5x 5x 5x 5x 5x 5x 5x 3x 1x 1x 2x 2x 2x 4x 5x 4x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 4x 1x 1x 3x 4x 4x 5x 5x 3x 3x 3x 5x 5x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 5x 5x 5x | import { Readable, Writable } from 'node:stream' import { FfmpegInput, InputDefinition } from './input' import { FfmpegOutput, OutputDefinition } from './output' import { FfmpegProcess, RunResult, RunOptions, ProcessOptions } from './process' import { FilterGraph, generateFilterGraph } from './utils/filters' export type CommandOptions = { input?: InputDefinition inputs?: InputDefinition[] output?: OutputDefinition outputs?: OutputDefinition[] complexFilters?: FilterGraph customArgs?: string[] } export class FfmpegCommand implements CommandOptions { inputs: FfmpegInput[] outputs: FfmpegOutput[] complexFilters?: FilterGraph customArgs: string[] constructor(options: CommandOptions) { if (options.input) { if (options.inputs) { throw new Error("Cannot specify both 'input' and 'inputs'") } options.inputs = [options.input] } if (options.output) { if (options.outputs) { throw new Error("Cannot specify both 'output' and 'outputs'") } options.outputs = [options.output] } this.inputs = (options.inputs || []).map( (inputOptions) => new FfmpegInput(inputOptions) ) this.outputs = (options.outputs || []).map( (outputOptions) => new FfmpegOutput(outputOptions) ) this.complexFilters = options.complexFilters this.customArgs = options.customArgs || [] this.#validateIO() } #validateIO(): void { if (this.inputs.filter((i) => i.isStream).length > 1) { throw new Error(`At most one stream input is supported`) } if (this.outputs.filter((o) => o.isStream).length > 1) { throw new Error(`At most one stream output is supported`) } } getFfmpegArguments(): string[] { let args: string[] = [] for (let input of this.inputs) { args.push(...input.getFfmpegArguments()) } args.push(...this.customArgs) if (this.complexFilters) { args.push('-filter_complex', generateFilterGraph(this.complexFilters)) } if (this.outputs.some((o) => o.isLocalFile)) { // Force overwrite outputs args.push('-y') } for (let output of this.outputs) { args.push(...output.getFfmpegArguments()) } return args } run(options: RunOptions): Promise<RunResult> { let procOtions: ProcessOptions = { args: this.getFfmpegArguments(), ...options } let streamInput = this.inputs.find((i) => i.isStream) if (streamInput) { procOtions.inputStream = streamInput.source as Readable } let streamOutput = this.outputs.find((i) => i.isStream) if (streamOutput) { procOtions.outputStream = streamOutput.target as Writable } return new FfmpegProcess(procOtions).run() } } |