• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

fluent-ffmpeg / node-fluent-ffmpeg / 6861990772

14 Nov 2023 10:00AM UTC coverage: 78.831% (-12.0%) from 90.801%
6861990772

Pull #1235

github

web-flow
Merge b91efd616 into 4e02d1257
Pull Request #1235: V3 experiments

157 of 170 branches covered (0.0%)

782 of 992 new or added lines in 13 files covered. (78.83%)

782 of 992 relevant lines covered (78.83%)

3.8 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

22.73
/src/process.ts
1
import { spawn } from 'child_process'
1!
2

1✔
3
import { isWindows } from './utils/platform'
1✔
4
import {
1✔
5
  extractErrorMessage,
1✔
6
  extractProgress,
1✔
7
  ProgressInfo,
1✔
8
  CodecData,
1✔
9
  CodecDataExtractor
1✔
10
} from './utils/parsing'
1✔
11
import LineBuffer from './utils/line-buffer'
1✔
12

1✔
13
export interface RunResult {
1✔
14
  stderr: string
1✔
15
  stdout: string
1✔
16
}
1✔
17

1✔
18
export interface RunOptions {
1✔
19
  nice?: number
1✔
20
  cwd?: string
1✔
21
  onProgress?: (progress: ProgressInfo) => void
1✔
22
  onCodecData?: (data: CodecData) => void
1✔
23
  onStderr?: (line: string) => void
1✔
24
}
1✔
25

1✔
26
export interface ProcessOptions extends RunOptions {
1✔
27
  args: string[]
1✔
28
  captureStdout?: boolean
1✔
29
}
1✔
30

1✔
NEW
31
export class FfmpegProcess implements ProcessOptions {
×
NEW
32
  args: string[]
×
NEW
33
  nice?: number
×
NEW
34
  cwd?: string
×
NEW
35
  captureStdout?: boolean
×
NEW
36
  onProgress?: (progress: ProgressInfo) => void
×
NEW
37
  onCodecData?: (data: CodecData) => void
×
NEW
38
  onStderr?: (line: string) => void
×
NEW
39

×
NEW
40
  constructor(options: ProcessOptions) {
×
NEW
41
    this.args = options.args
×
NEW
42
    this.nice = options.nice
×
NEW
43
    this.cwd = options.cwd
×
NEW
44
    this.captureStdout = options.captureStdout
×
NEW
45
    this.onProgress = options.onProgress
×
NEW
46
    this.onCodecData = options.onCodecData
×
NEW
47
    this.onStderr = options.onStderr
×
NEW
48
  }
×
NEW
49

×
NEW
50
  run(callback?: (err: any, result?: any) => any): Promise<RunResult> {
×
NEW
51
    let cmd = process.env.FFMPEG_PATH || 'ffmpeg'
×
NEW
52
    let args: string[] = [...this.args]
×
NEW
53

×
NEW
54
    let { onProgress, onCodecData, onStderr } = this
×
NEW
55

×
NEW
56
    if (this.nice && this.nice !== 0 && !isWindows) {
×
NEW
57
      args = ['-n', this.nice.toString(), cmd, ...args]
×
NEW
58
      cmd = 'nice'
×
NEW
59
    }
×
NEW
60

×
NEW
61
    let promise: Promise<RunResult> = new Promise((resolve, reject) => {
×
NEW
62
      let child = spawn(cmd, args, {
×
NEW
63
        cwd: this.cwd,
×
NEW
64
        windowsHide: true
×
NEW
65
      })
×
NEW
66

×
NEW
67
      let stderr = new LineBuffer()
×
NEW
68
      let stdout = new LineBuffer()
×
NEW
69

×
NEW
70
      if (onStderr) {
×
NEW
71
        stderr.on('line', onStderr)
×
NEW
72
      }
×
NEW
73

×
NEW
74
      if (onProgress) {
×
NEW
75
        stderr.on('line', (line: string) => {
×
NEW
76
          let progress = extractProgress(line)
×
NEW
77
          if (progress) {
×
NEW
78
            onProgress?.(progress)
×
NEW
79
          }
×
NEW
80
        })
×
NEW
81
      }
×
NEW
82

×
NEW
83
      if (onCodecData) {
×
NEW
84
        let extractor = new CodecDataExtractor(onCodecData)
×
NEW
85
        stderr.on('line', (line: string) => {
×
NEW
86
          if (!extractor.done) {
×
NEW
87
            extractor.processLine(line)
×
NEW
88
          }
×
NEW
89
        })
×
NEW
90
      }
×
NEW
91

×
NEW
92
      child.on('error', (err) => reject(err))
×
NEW
93

×
NEW
94
      child.on('close', (code, signal) => {
×
NEW
95
        stderr.close()
×
NEW
96
        stdout.close()
×
NEW
97

×
NEW
98
        if (signal) {
×
NEW
99
          reject(new Error(`ffmpeg was killed with signal ${signal}`))
×
NEW
100
        } else if (code) {
×
NEW
101
          reject(
×
NEW
102
            new Error(
×
NEW
103
              `ffmpeg exited with code ${code}:\n ${extractErrorMessage(
×
NEW
104
                stderr.lines
×
NEW
105
              )}`
×
NEW
106
            )
×
NEW
107
          )
×
NEW
108
        } else {
×
NEW
109
          resolve({
×
NEW
110
            stdout: stdout.toString(),
×
NEW
111
            stderr: stderr.toString()
×
NEW
112
          })
×
NEW
113
        }
×
NEW
114
      })
×
NEW
115

×
NEW
116
      if (this.captureStdout) {
×
NEW
117
        child.stdout.on('data', (data) => stdout.append(data.toString()))
×
NEW
118
      }
×
NEW
119

×
NEW
120
      child.stderr.on('data', (data) => stderr.append(data.toString()))
×
NEW
121
    })
×
NEW
122

×
NEW
123
    if (callback) {
×
NEW
124
      promise.then(
×
NEW
125
        (value) => callback(null, value),
×
NEW
126
        (reason) => callback(reason)
×
NEW
127
      )
×
NEW
128
    }
×
NEW
129

×
NEW
130
    return promise
×
NEW
131
  }
×
NEW
132
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc