All files / src input.ts

100% Statements 92/92
100% Branches 21/21
100% Functions 7/7
100% Lines 92/92

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 931x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 21x 21x 21x 21x 21x 21x 21x 21x 21x 21x 12x 12x 21x 21x 21x 21x 21x 21x 21x 21x 21x 21x 15x 15x 21x 21x 8x 2x 8x 6x 6x 6x 8x 21x 21x 11x 8x 11x 3x 3x 11x 21x 21x 11x 11x 11x 2x 2x 11x 11x 1x 11x 2x 2x 11x 11x 1x 1x 11x 11x 1x 1x 11x 11x 11x 21x 21x 11x 11x 11x 11x 11x 11x 11x 21x  
import { Readable } from 'node:stream'
 
import { protocolRegexp } from './utils/regexp'
 
export type InputSource = string | Readable
 
export type InputOptions = {
  source: InputSource
  format?: string
  fps?: 'native' | number
  seek?: string | number
  loop?: boolean
  customArgs?: string[]
}
 
export type InputDefinition = InputOptions | InputSource
 
export class FfmpegInput implements InputOptions {
  source: InputSource
  format?: string
  fps?: 'native' | number
  seek?: string | number
  loop?: boolean
  customArgs: string[]
 
  constructor(options: InputDefinition) {
    if (typeof options === 'string' || options instanceof Readable) {
      options = { source: options }
    }
 
    this.source = options.source
    this.format = options.format
    this.fps = options.fps
    this.seek = options.seek
    this.loop = options.loop
    this.customArgs = options.customArgs || []
  }
 
  get isStream(): boolean {
    return this.source instanceof Readable
  }
 
  get isLocalFile(): boolean {
    if (this.source instanceof Readable || this.format === 'lavfi') {
      return false
    } else {
      let protocol = this.source.match(protocolRegexp)
      return !protocol || protocol[1] === 'file'
    }
  }
 
  #getSourceString(): string {
    if (typeof this.source === 'string') {
      return this.source
    } else {
      return 'pipe:0'
    }
  }
 
  #getOptions(): string[] {
    let options: string[] = []
 
    if (this.format) {
      options.push('-f', this.format)
    }
 
    if (this.fps === 'native') {
      options.push('-re')
    } else if (this.fps) {
      options.push('-r', this.fps.toString())
    }
 
    if (this.seek) {
      options.push('-ss', this.seek.toString())
    }
 
    if (this.loop) {
      options.push('-loop', '1')
    }
 
    return options
  }
 
  getFfmpegArguments(): string[] {
    return [
      ...this.#getOptions(),
      ...this.customArgs,
      '-i',
      this.#getSourceString()
    ]
  }
}