mediasnacks 0.23.0 → 0.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/dropdups.js +3 -5
- package/src/hev1tohvc1.js +0 -1
- package/src/prores.js +39 -18
package/package.json
CHANGED
package/src/dropdups.js
CHANGED
|
@@ -4,10 +4,10 @@ import { resolve, parse, format } from 'node:path'
|
|
|
4
4
|
|
|
5
5
|
import { parseOptions } from './utils/parseOptions.js'
|
|
6
6
|
import { ffmpeg, assertUserHasFFmpeg, run } from './utils/subprocess.js'
|
|
7
|
-
import {
|
|
7
|
+
import { ProresProfiles } from './prores.js'
|
|
8
8
|
|
|
9
9
|
|
|
10
|
-
const PROFILE =
|
|
10
|
+
const PROFILE = ProresProfiles.default
|
|
11
11
|
|
|
12
12
|
const HELP = `
|
|
13
13
|
SYNOPSIS
|
|
@@ -65,9 +65,7 @@ async function dropdups(video, dupFrameNum) {
|
|
|
65
65
|
? `decimate=cycle=${dupFrameNum}`
|
|
66
66
|
: 'mpdecimate,setpts=N/FRAME_RATE/TB',
|
|
67
67
|
'-fps_mode', 'cfr',
|
|
68
|
-
'-c:v', 'prores_ks',
|
|
69
|
-
'-profile:v', PROFILE,
|
|
70
|
-
'-pix_fmt', 'yuv422p10le',
|
|
68
|
+
'-c:v', 'prores_ks', '-profile:v', PROFILE,
|
|
71
69
|
makeOutputPath(video)
|
|
72
70
|
])
|
|
73
71
|
}
|
package/src/hev1tohvc1.js
CHANGED
package/src/prores.js
CHANGED
|
@@ -3,13 +3,24 @@ import { resolve, parse, join } from 'node:path'
|
|
|
3
3
|
import { parseOptions } from './utils/parseOptions.js'
|
|
4
4
|
import { assertUserHasFFmpeg, run } from './utils/subprocess.js'
|
|
5
5
|
|
|
6
|
-
export const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
6
|
+
export const ProresProfiles = new class {
|
|
7
|
+
// https://github.com/oyvindln/vhs-decode/wiki/ProRes-The-Definitive-FFmpeg-Guide#profiles-can-be-the-following
|
|
8
|
+
profiles = {
|
|
9
|
+
// 10-bit
|
|
10
|
+
0: 'proxy',
|
|
11
|
+
1: 'lt',
|
|
12
|
+
2: 'standard',
|
|
13
|
+
3: 'hq',
|
|
14
|
+
|
|
15
|
+
// 12-bit
|
|
16
|
+
4: '4444',
|
|
17
|
+
5: '4444xq'
|
|
18
|
+
}
|
|
19
|
+
default = 3
|
|
20
|
+
|
|
21
|
+
list = () => Object.keys(this.profiles)
|
|
22
|
+
isValid = n => Object.hasOwn(this.profiles, n)
|
|
23
|
+
table = () => Object.entries(this.profiles)
|
|
13
24
|
}
|
|
14
25
|
|
|
15
26
|
const HELP = `
|
|
@@ -17,15 +28,21 @@ SYNOPSIS
|
|
|
17
28
|
mediasnacks prores [options] <video>
|
|
18
29
|
|
|
19
30
|
DESCRIPTION
|
|
20
|
-
Converts a video to ProRes
|
|
31
|
+
Converts a video to ProRes
|
|
21
32
|
|
|
22
33
|
OPTIONS
|
|
23
|
-
-p, --profile <n>
|
|
34
|
+
-p, --profile <n> Default: 3 (422 HQ 10-bit)
|
|
35
|
+
-s, --start <time> Start time (e.g. 5.0). Default: beginning.
|
|
36
|
+
-e, --end <time> End time (e.g. 0:10.0). Default: end of video.
|
|
24
37
|
-h, --help
|
|
25
38
|
|
|
39
|
+
PROFILES
|
|
40
|
+
${ProresProfiles.table().map(([num, name]) =>
|
|
41
|
+
` ${num}: ${name}`).join('\n')}
|
|
42
|
+
|
|
26
43
|
EXAMPLES
|
|
27
44
|
mediasnacks prores video.mov
|
|
28
|
-
mediasnacks prores
|
|
45
|
+
mediasnacks prores -p2 *.mov
|
|
29
46
|
|
|
30
47
|
Both output a file named: video.prores.mov
|
|
31
48
|
`.trim()
|
|
@@ -35,7 +52,9 @@ async function main() {
|
|
|
35
52
|
await assertUserHasFFmpeg()
|
|
36
53
|
|
|
37
54
|
const { values, files } = await parseOptions({
|
|
38
|
-
profile: { short: 'p', type: 'string', default: String(
|
|
55
|
+
profile: { short: 'p', type: 'string', default: String(ProresProfiles.default) },
|
|
56
|
+
start: { short: 's', type: 'string', default: '' },
|
|
57
|
+
end: { short: 'e', type: 'string', default: '' },
|
|
39
58
|
help: { short: 'h', type: 'boolean' },
|
|
40
59
|
})
|
|
41
60
|
|
|
@@ -44,6 +63,9 @@ async function main() {
|
|
|
44
63
|
return
|
|
45
64
|
}
|
|
46
65
|
|
|
66
|
+
if (!ProresProfiles.isValid(Number(values.profile)))
|
|
67
|
+
throw new Error('Invalid profile. Must be one of: ' + ProresProfiles.list().join(','))
|
|
68
|
+
|
|
47
69
|
if (files.length !== 1)
|
|
48
70
|
throw new Error('Expected 1 argument: video file. See mediasnacks prores --help')
|
|
49
71
|
|
|
@@ -51,20 +73,19 @@ async function main() {
|
|
|
51
73
|
const { name, dir } = parse(video)
|
|
52
74
|
const output = join(dir, `${name}.prores.mov`)
|
|
53
75
|
|
|
54
|
-
|
|
55
|
-
await prores(video, values.profile, output)
|
|
76
|
+
await prores(video, values.start, values.end, values.profile, output)
|
|
56
77
|
}
|
|
57
78
|
|
|
58
|
-
async function prores(video, profile, output) {
|
|
79
|
+
async function prores(video, start, end, profile, output) {
|
|
59
80
|
await run('ffmpeg', [
|
|
60
81
|
'-v', 'error',
|
|
61
82
|
'-stats',
|
|
83
|
+
start ? ['-ss', start] : [],
|
|
84
|
+
end ? ['-to', end] : [],
|
|
62
85
|
'-i', video,
|
|
63
|
-
'-c:v', 'prores_ks',
|
|
64
|
-
'-profile:v', profile,
|
|
65
|
-
'-pix_fmt', 'yuv422p10le',
|
|
86
|
+
'-c:v', 'prores_ks', '-profile:v', profile,
|
|
66
87
|
output
|
|
67
|
-
])
|
|
88
|
+
].flat())
|
|
68
89
|
}
|
|
69
90
|
|
|
70
91
|
if (import.meta.main)
|