forked from mifi/editly
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcli.js
128 lines (102 loc) · 3.99 KB
/
cli.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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#!/usr/bin/env node
const meow = require('meow');
const fs = require('fs');
const FileType = require('file-type');
const pMap = require('p-map');
const JSON5 = require('json5');
const assert = require('assert');
const editly = require('.');
// See also readme
const cli = meow(`
Usage
$ editly CLIP1 [CLIP2 [CLIP3 ...]]
where each CLIP can be one of the following:
- A path to a video file
- A path to an image
- A quoted text to show in a title screen, prefixed by "title:"
Or alternatively:
$ editly --json JSON_PATH
where JSON_PATH is the path to an edit spec JSON file, can be a normal JSON or JSON5
Options
--out Out video path (defaults to ./editly-out.mp4) - can also be a .gif
--json Use JSON edit spec
--transition-name Name of default transition to use (default: random)
--transition-duration Default transition duration
--clip-duration Default clip duration
--width Width which all media will be converted to
--height Height which all media will be converted to
--fps FPS which all videos will be converted to
--font-path Set default font to a .ttf
--audio-file-path Add an audio track
--fast, -f Fast mode (low resolution and FPS, useful for getting a quick preview)
--verbose, -v
For more detailed explanation, see:
https://github.com/mifi/editly
Examples
$ editly title:'My video' clip1.mov clip2.mov title:'My slideshow' img1.jpg img2.jpg title:'THE END' --audio-file-path /path/to/music.mp3 --font-path /path/to/my-favorite-font.ttf
$ editly my-editly.json5 --out output.gif
`, {
flags: {
verbose: { type: 'boolean', alias: 'v' },
fast: { type: 'boolean', alias: 'f' },
transitionDuration: { type: 'number' },
clipDuration: { type: 'number' },
width: { type: 'number' },
height: { type: 'number' },
fps: { type: 'number' },
},
});
(async () => {
let { json } = cli.flags;
// eslint-disable-next-line prefer-destructuring
if (cli.input.length === 1 && /\.(json|json5|js)$/.test(cli.input[0].toLowerCase())) json = cli.input[0];
let params = {
defaults: {},
};
if (json) {
params = JSON5.parse(fs.readFileSync(json, 'utf-8'));
} else {
const clipsIn = cli.input;
if (clipsIn.length < 1) cli.showHelp();
const clips = await pMap(clipsIn, async (clip) => {
const match = clip.match(/^title:(.+)$/);
if (match) return { type: 'title-background', text: match[1] };
const fileType = await FileType.fromFile(clip);
if (!fileType) {
console.error('Invalid file for clip', clip);
cli.showHelp();
}
const { mime } = fileType;
if (mime.startsWith('video')) return { type: 'video', path: clip };
if (mime.startsWith('image')) return { type: 'image', path: clip };
throw new Error(`Unrecognized clip or file type "${clip}"`);
}, { concurrency: 1 });
assert(clips.length > 0, 'No clips specified');
params.clips = clips.map((clip) => ({ layers: [clip] }));
}
const { verbose, transitionName, transitionDuration, clipDuration, width, height, fps, audioFilePath, fontPath, fast, out: outPath } = cli.flags;
if (transitionName || transitionDuration != null) {
params.defaults.transition = {};
if (transitionName) params.defaults.transition.name = transitionName;
if (transitionDuration) params.defaults.transition.duration = transitionDuration;
}
if (clipDuration) params.defaults.duration = clipDuration;
if (fontPath) {
params.defaults.layer = {
fontPath,
};
}
if (outPath) params.outPath = outPath;
if (audioFilePath) params.audioFilePath = audioFilePath;
if (width) params.width = width;
if (height) params.height = height;
if (fps) params.fps = fps;
if (fast) params.fast = fast;
if (verbose) params.verbose = verbose;
if (params.verbose) console.log(JSON5.stringify(params, null, 2));
if (!params.outPath) params.outPath = './editly-out.mp4';
await editly(params);
})().catch((err) => {
console.error(err);
process.exitCode = 1;
});