-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathconvert-video.js
More file actions
executable file
·113 lines (97 loc) · 2.68 KB
/
convert-video.js
File metadata and controls
executable file
·113 lines (97 loc) · 2.68 KB
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
110
111
112
113
#!/usr/bin/env node
/* eslint-disable import/no-extraneous-dependencies, no-console */
const fs = require('fs')
const { parse, join } = require('path')
const ffmpeg = require('fluent-ffmpeg')
const prettyBytes = require('pretty-bytes')
const { hideBin } = require('yargs/helpers')
const yargs = require('yargs/yargs')
const { argv } = yargs(hideBin(process.argv))
.command(
'convert-video [options] <video-files...>',
'convert video for use on web page',
() => {},
(argv) => {
console.info(argv)
},
)
.option('dest', {
alias: 'd',
type: 'string',
description: 'folder where to save optimized files',
default: '',
})
.option('res', {
alias: 'r',
type: 'number',
description: 'output resolution',
default: 1440,
})
.option('fps', {
type: 'number',
description: 'frames per second',
default: 10,
})
.demandCommand(1)
const awaitEach = (items = [], callback) =>
items.reduce(
(acc, item, index) =>
Promise.resolve(acc).then(() => callback(item, index)),
Promise.resolve,
)
const getFilesizeInBytes = (filename) => {
const stats = fs.statSync(filename)
return stats.size
}
const getFileSize = (filename) => {
const biteSize = getFilesizeInBytes(filename)
return prettyBytes(biteSize)
}
const logResult = (filename) => {
console.log(` -- generated ${filename} (${getFileSize(filename)})`)
}
const ffmpegPromise = (input, output, callback) =>
new Promise((resolve, reject) => {
const command = ffmpeg(input)
.output(output)
.on('error', (err) => {
console.info(`[ffmpeg] error: ${err.message}`)
reject(err)
})
.on('end', () => {
logResult(output)
resolve()
})
callback(command).run()
})
async function main() {
await awaitEach(argv._, async (file, index) => {
console.log(
`${index ? '\n' : ''}Processing ${file} (${getFileSize(file)})...`,
)
const { name } = parse(file)
// generate Poster
await ffmpegPromise(file, join(argv.dest, `${name}.jpg`), (command) =>
command.size(`${argv.res}x?`).outputOptions(['-vframes 1', '-q:v 1']),
)
// generate WEBM
await ffmpegPromise(file, join(argv.dest, `${name}.webm`), (command) =>
command
.noAudio()
.fps(argv.fps)
.size(`${argv.res}x?`)
.outputOptions(['-c vp9', '-b:v 0', '-crf 41']),
)
await ffmpegPromise(file, join(argv.dest, `${name}.mp4`), (command) =>
command
.noAudio()
.fps(argv.fps)
.size(`${argv.res}x?`)
.videoCodec('libx264')
.outputOptions(['-movflags +faststart', '-b:v 0', '-crf 25'])
.format('mp4'),
)
})
process.exit(0)
}
main()