mediasnacks 0.1.0 → 0.2.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/.zsh/completions/_mediasnacks +3 -2
- package/README.md +5 -1
- package/package.json +1 -1
- package/src/avif.js +0 -1
- package/src/cli.js +22 -28
- package/src/dropdups.js +10 -11
- package/src/framediff.sh +3 -1
- package/src/vconcat.sh +22 -0
- package/src/videodiff.sh +7 -1
|
@@ -9,7 +9,8 @@ _mediasnacks_commands=(
|
|
|
9
9
|
'qdir:Sequentially runs all *.sh files in a folder'
|
|
10
10
|
'hev1tohvc1:Fixes video thumbnails not rendering in macOS Finder'
|
|
11
11
|
'framediff:ffplay with a filter for diffing adjacent frames'
|
|
12
|
-
'videodiff:Plays a video
|
|
12
|
+
'videodiff:Plays a video with the difference of two videos'
|
|
13
|
+
'vconcat:Concatenates videos'
|
|
13
14
|
)
|
|
14
15
|
|
|
15
16
|
_mediasnacks() {
|
|
@@ -20,7 +21,7 @@ _mediasnacks() {
|
|
|
20
21
|
|
|
21
22
|
local cmd="$words[2]"
|
|
22
23
|
case "$cmd" in
|
|
23
|
-
avif|resize|moov2front|dropdups|seqcheck|hev1tohvc1|framediff|videodiff)
|
|
24
|
+
avif|resize|moov2front|dropdups|seqcheck|hev1tohvc1|framediff|videodiff|vconcat)
|
|
24
25
|
_files
|
|
25
26
|
;;
|
|
26
27
|
qdir)
|
package/README.md
CHANGED
|
@@ -18,7 +18,11 @@ Commands:
|
|
|
18
18
|
- `seqcheck` Finds missing sequence number
|
|
19
19
|
- `qdir` Sequentially runs all *.sh files in a folder
|
|
20
20
|
- `hev1tohvc1`: Fixes video thumbnails not rendering in macOS Finder
|
|
21
|
-
|
|
21
|
+
|
|
22
|
+
- `framediff`: Plays a video of adjacent frames diff
|
|
23
|
+
- `videodiff`: Plays a video with the difference of two videos
|
|
24
|
+
-
|
|
25
|
+
- `vconcat`: Concatenates videos
|
|
22
26
|
<br/>
|
|
23
27
|
|
|
24
28
|
### Converting Images to AVIF
|
package/package.json
CHANGED
package/src/avif.js
CHANGED
package/src/cli.js
CHANGED
|
@@ -6,34 +6,27 @@ import pkgJSON from '../package.json' with { type: 'json' }
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
const COMMANDS = {
|
|
9
|
-
avif:
|
|
10
|
-
resize:
|
|
11
|
-
moov2front:
|
|
12
|
-
|
|
13
|
-
dropdups:
|
|
14
|
-
seqcheck:
|
|
15
|
-
qdir:
|
|
16
|
-
hev1tohvc1:
|
|
9
|
+
avif: ['avif.js', 'Converts images to AVIF'],
|
|
10
|
+
resize: ['resize.js', 'Resizes videos or images'],
|
|
11
|
+
moov2front: ['moov2front.js', 'Rearranges .mov and .mp4 metadata for fast-start streaming'],
|
|
12
|
+
|
|
13
|
+
dropdups: ['dropdups.js', 'Removes duplicate frames in a video'],
|
|
14
|
+
seqcheck: ['seqcheck.js', 'Finds missing sequence number'],
|
|
15
|
+
qdir: ['qdir.js', 'Sequentially runs all *.sh files in a folder'],
|
|
16
|
+
hev1tohvc1: ['hev1tohvc1.js', 'Fixes video thumbnails not rendering in macOS Finder '],
|
|
17
|
+
|
|
18
|
+
framediff: ['framediff.sh', 'Plays a video of adjacent frames diff'],
|
|
19
|
+
videodiff: ['videodiff.sh', 'Plays a video with the difference of two videos'],
|
|
17
20
|
|
|
18
|
-
|
|
19
|
-
videodiff: join(import.meta.dirname, 'videodiff.sh'),
|
|
21
|
+
vconcat: ['vconcat.sh', 'Concatenates videos'],
|
|
20
22
|
}
|
|
21
23
|
|
|
22
24
|
const USAGE = `
|
|
23
25
|
Usage: npx mediasnacks <command> <args>
|
|
24
26
|
|
|
25
27
|
Commands:
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
moov2front: Rearranges .mov and .mp4 metadata for fast-start streaming
|
|
29
|
-
|
|
30
|
-
dropdups: Removes duplicate frames in a video
|
|
31
|
-
seqcheck: Finds missing sequence number
|
|
32
|
-
qdir: Sequentially runs all *.sh files in a folder
|
|
33
|
-
hev1tohvc1: Fixes video thumbnails not rendering in macOS Finder
|
|
34
|
-
|
|
35
|
-
framediff: Plays a video of adjacent frames diff
|
|
36
|
-
videodiff: Plays a video of the difference of two videos
|
|
28
|
+
${Object.entries(COMMANDS).map(([cmd, [, title]]) =>
|
|
29
|
+
` ${cmd}\t${title}`).join('\n')}
|
|
37
30
|
`.trim()
|
|
38
31
|
|
|
39
32
|
|
|
@@ -55,13 +48,14 @@ if (!opt) {
|
|
|
55
48
|
}
|
|
56
49
|
|
|
57
50
|
if (!Object.hasOwn(COMMANDS, opt)) {
|
|
58
|
-
console.error(`'${opt}' is not a
|
|
51
|
+
console.error(`'${opt}' is not a command. See npx mediasnacks --help\n`)
|
|
59
52
|
process.exit(1)
|
|
60
53
|
}
|
|
61
54
|
|
|
62
|
-
const cmd = COMMANDS[opt]
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
: process.execPath
|
|
66
|
-
|
|
67
|
-
|
|
55
|
+
const cmd = join(import.meta.dirname, COMMANDS[opt][0])
|
|
56
|
+
const isShellScript = cmd.endsWith('.sh')
|
|
57
|
+
spawn(
|
|
58
|
+
isShellScript ? cmd : process.execPath,
|
|
59
|
+
isShellScript ? args : [cmd, ...args],
|
|
60
|
+
{ stdio: 'inherit' }
|
|
61
|
+
).on('exit', process.exit)
|
package/src/dropdups.js
CHANGED
|
@@ -14,6 +14,8 @@ const PRORES_PROFILES = {
|
|
|
14
14
|
'4444': 4,
|
|
15
15
|
'4444xq': 5,
|
|
16
16
|
}
|
|
17
|
+
const PROFILE = PRORES_PROFILES.hq
|
|
18
|
+
|
|
17
19
|
|
|
18
20
|
const USAGE = `
|
|
19
21
|
Usage: npx mediasnacks dropdups [-n <bad-frame-number>] <video>
|
|
@@ -22,8 +24,9 @@ Removes duplicate frames and outputs ProRes 422 HQ.
|
|
|
22
24
|
|
|
23
25
|
Options:
|
|
24
26
|
-n, --bad-frame-number <n> Known frame interval to drop.
|
|
25
|
-
|
|
26
|
-
|
|
27
|
+
(default: n=0) auto-detects repeated frames (slower)
|
|
28
|
+
Ex.A: Use n=2 when every other frame is repeated.
|
|
29
|
+
Ex.B: Use n=6 if e.g., a 25 fps got upped to 30 fps without interpolation.
|
|
27
30
|
-h, --help
|
|
28
31
|
`.trim()
|
|
29
32
|
|
|
@@ -31,7 +34,7 @@ Options:
|
|
|
31
34
|
async function main() {
|
|
32
35
|
const { values, positionals } = parseArgs({
|
|
33
36
|
options: {
|
|
34
|
-
'bad-frame-number': { short: 'n', type: 'string' },
|
|
37
|
+
'bad-frame-number': { short: 'n', type: 'string', default: '' },
|
|
35
38
|
help: { short: 'h', type: 'boolean', default: false },
|
|
36
39
|
},
|
|
37
40
|
allowPositionals: true
|
|
@@ -45,13 +48,9 @@ async function main() {
|
|
|
45
48
|
if (!positionals.length)
|
|
46
49
|
throw new Error('No video specified. See npx mediasnacks dropdups --help')
|
|
47
50
|
|
|
48
|
-
let nBadFrame =
|
|
49
|
-
if (
|
|
50
|
-
|
|
51
|
-
if (!Number.isFinite(n) || n <= 0)
|
|
52
|
-
throw new Error('Invalid --bad-frame-number. It must be a positive integer.')
|
|
53
|
-
nBadFrame = n
|
|
54
|
-
}
|
|
51
|
+
let nBadFrame = values['bad-frame-number']
|
|
52
|
+
if (nBadFrame && /^\d+$/.test(nBadFrame))
|
|
53
|
+
throw new Error('Invalid --bad-frame-number. It must be a positive integer.')
|
|
55
54
|
|
|
56
55
|
await assertUserHasFFmpeg()
|
|
57
56
|
|
|
@@ -72,7 +71,7 @@ async function drop(video, nBadFrame) {
|
|
|
72
71
|
: 'mpdecimate,setpts=N/FRAME_RATE/TB',
|
|
73
72
|
'-fps_mode', 'cfr',
|
|
74
73
|
'-c:v', 'prores_ks',
|
|
75
|
-
'-profile:v',
|
|
74
|
+
'-profile:v', PROFILE,
|
|
76
75
|
'-pix_fmt', 'yuv422p10le',
|
|
77
76
|
makeOutputPath(video)
|
|
78
77
|
])
|
package/src/framediff.sh
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
|
|
1
3
|
# Plays a video with a filter for diffing adjacent frames.
|
|
2
4
|
# I use this for finding repeated frames. For example, you’ll see
|
|
3
5
|
# a black frame if two consecutive frames are almost similar.
|
|
4
6
|
|
|
5
7
|
# The frame number is rendered at the top-left.
|
|
6
8
|
|
|
7
|
-
ffplay -hide_banner "$1" -vf "
|
|
9
|
+
ffplay -hide_banner -xerror "$1" -vf "
|
|
8
10
|
tblend=all_mode=difference,
|
|
9
11
|
format=gray,
|
|
10
12
|
drawtext=text='%{n}':x=20:y=20:fontcolor=white:fontsize=48
|
package/src/vconcat.sh
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#!/bin/zsh
|
|
2
|
+
|
|
3
|
+
if (( $# < 2 )); then
|
|
4
|
+
cat << EOF
|
|
5
|
+
Usage:
|
|
6
|
+
$(basename $0) vid1.mov vid2.mov [...]
|
|
7
|
+
$(basename $0) *.mp4
|
|
8
|
+
EOF
|
|
9
|
+
exit 1
|
|
10
|
+
fi
|
|
11
|
+
|
|
12
|
+
list_file=$(mktemp -p .)
|
|
13
|
+
for file in "$@"; do
|
|
14
|
+
echo "file '$file'" >> "$list_file"
|
|
15
|
+
done
|
|
16
|
+
|
|
17
|
+
first_video="$1"
|
|
18
|
+
outfile="${first_video:r}.concat.${first_video:e}"
|
|
19
|
+
|
|
20
|
+
ffmpeg -v error -f concat -safe 0 -i "$list_file" -c copy "$outfile"
|
|
21
|
+
|
|
22
|
+
rm "$list_file"
|
package/src/videodiff.sh
CHANGED
|
@@ -1,9 +1,15 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
|
|
1
3
|
# Diffs two video files
|
|
2
4
|
# The videos must have the same resolution and ideally the same framerate.
|
|
3
5
|
video1="$1"
|
|
4
6
|
video2="$2"
|
|
5
7
|
|
|
6
|
-
|
|
8
|
+
ffprobe -v error "$video1" || exit 1
|
|
9
|
+
ffprobe -v error "$video2" || exit 1
|
|
10
|
+
|
|
11
|
+
ffplay -hide_banner \
|
|
12
|
+
-f lavfi "movie=$video1 [a]; movie=$video2 [b]; [a][b] blend=all_mode=difference128"
|
|
7
13
|
|
|
8
14
|
#all_mode=difference: absolute diff (ideal for detecting visual changes)
|
|
9
15
|
#all_mode=subtract: raw subtraction (can go <0, may appear darker)
|