mediasnacks 0.1.1 → 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.
@@ -10,6 +10,7 @@ _mediasnacks_commands=(
10
10
  'hev1tohvc1:Fixes video thumbnails not rendering in macOS Finder'
11
11
  'framediff:ffplay with a filter for diffing adjacent frames'
12
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
@@ -21,6 +21,8 @@ Commands:
21
21
 
22
22
  - `framediff`: Plays a video of adjacent frames diff
23
23
  - `videodiff`: Plays a video with the difference of two videos
24
+ -
25
+ - `vconcat`: Concatenates videos
24
26
  <br/>
25
27
 
26
28
  ### Converting Images to AVIF
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mediasnacks",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "Utilities for preparing videos, images, and audio for the web",
5
5
  "license": "MIT",
6
6
  "author": "Eric Fortis",
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: join(import.meta.dirname, 'avif.js'),
10
- resize: join(import.meta.dirname, 'resize.js'),
11
- moov2front: join(import.meta.dirname, 'moov2front.js'),
12
-
13
- dropdups: join(import.meta.dirname, 'dropdups.js'),
14
- seqcheck: join(import.meta.dirname, 'seqcheck.js'),
15
- qdir: join(import.meta.dirname, 'qdir.js'),
16
- hev1tohvc1: join(import.meta.dirname, 'hev1tohvc1.js'),
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
- framediff: join(import.meta.dirname, 'framediff.sh'),
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
- avif: Converts images to AVIF
27
- resize: Resizes videos or images
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 with 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 mediasnacks command. See npx mediasnacks --help\n`)
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 executable = cmd.endsWith('.sh')
64
- ? 'sh'
65
- : process.execPath
66
- spawn(executable, [cmd, ...args], { stdio: 'inherit' })
67
- .on('exit', code => process.exit(code))
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/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
- ffplay -f lavfi "movie=$video1 [a]; movie=$video2 [b]; [a][b] blend=all_mode=difference128"
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)