-
Notifications
You must be signed in to change notification settings - Fork 26
/
videoconcat.js
109 lines (86 loc) · 2.21 KB
/
videoconcat.js
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
108
109
'use strict';
let tmp = require('tmp');
let fext = require('file-extension');
let fs = require('fs');
let shelljs = require('shelljs');
let _ = require('lodash');
module.exports = function (spec) {
let that = null;
let clips = [];
let outputFileName = tmp.tmpNameSync({
prefix: 'video-output-',
postfix: '.mp4'
});
spec = _.defaults(spec, {
silent: true,
overwrite: null,
ffmpeg_path:'ffmpeg'
});
function handleOverwrite() {
switch (spec.overwrite) {
case true:
return '-y'
case false:
return '-n'
default:
return ''
}
}
function setClips(_clips) {
if (Array.isArray(_clips)) {
clips = _clips;
} else {
throw new Error('Expected parameter to be of type `Array`');
}
return that;
}
function setOutput(fileName) {
if (fileName) {
outputFileName = fileName;
}
return that;
}
/**
* concatenates clips together using a fileList
* @param {string} args.fileList Address of a text file containing filenames of the clips
* @return {[type]} [description]
*/
function concatClips(args) {
const overwrite = handleOverwrite();
return new Promise((resolve, reject) => {
let child = shelljs.exec(`${spec.ffmpeg_path} -f concat -safe 0 -protocol_whitelist file,http,https,tcp,tls,crypto -i ${args.fileList} -c copy ${outputFileName} ${overwrite}`, { async: true, silent: spec.silent });
child.on('exit', (code, signal) => {
if (code === 0) {
resolve(outputFileName);
} else {
reject();
}
});
});
}
function escapePath(pathString) {
return pathString.replace(/\\/g, '\\\\');
}
function getLineForClip(clip) {
return `file '${escapePath(clip.fileName)}'`;
}
function getTextForClips(clips) {
return clips.map(getLineForClip).join('\n');
}
function doConcat() {
let fileListText = getTextForClips(clips);
let fileListFilename = tmp.tmpNameSync({
postfix: '.txt'
});
fs.writeFileSync(fileListFilename, fileListText, 'utf8');
return concatClips({
fileList: fileListFilename,
});
}
that = Object.create({
clips: setClips,
output: setOutput,
concat: doConcat,
});
return that;
}