mediasnacks 0.16.1 → 0.16.3
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 +9 -3
- package/README.md +21 -16
- package/package.json +1 -1
- package/src/avif.js +1 -1
- package/src/cli.js +6 -4
- package/src/dropdups.js +1 -1
- package/src/edgespic.js +1 -1
- package/src/flattendir.test.js +36 -0
- package/src/hev1tohvc1.js +1 -1
- package/src/moov2front.js +1 -1
- package/src/qdir.js +1 -2
- package/src/resize.js +1 -1
- package/src/seqcheck.js +1 -2
- package/src/sqcrop.js +1 -1
- package/src/unemoji.sh +3 -0
- package/src/utils/test-utils.js +10 -1
- package/src/vsplit.js +1 -1
|
@@ -3,24 +3,30 @@
|
|
|
3
3
|
_mediasnacks_commands=(
|
|
4
4
|
'avif:Converts images to AVIF'
|
|
5
5
|
'sqcrop:Square crops images'
|
|
6
|
-
|
|
6
|
+
|
|
7
|
+
'resize:Resizes videos or images'
|
|
7
8
|
'edgespic:Extracts first and last frames'
|
|
8
|
-
'framediff:ffplay with a filter for diffing adjacent frames'
|
|
9
9
|
'gif:Video to GIF'
|
|
10
|
+
|
|
11
|
+
'dropdups:Removes duplicate frames in a video'
|
|
12
|
+
'framediff:ffplay with a filter for diffing adjacent frames'
|
|
10
13
|
'hev1tohvc1:Fixes video thumbnails not rendering in macOS Finder'
|
|
11
14
|
'moov2front:Rearranges metadata for fast-start streaming'
|
|
12
|
-
'resize:Resizes videos or images'
|
|
13
15
|
'vconcat:Concatenates videos'
|
|
14
16
|
'vdiff:Plays a video with the difference of two videos'
|
|
15
17
|
'vsplit:Splits a video into multiple clips from CSV timestamps'
|
|
16
18
|
'vtrim:Trims video from start to end time'
|
|
19
|
+
|
|
17
20
|
'flattendir:Moves unique files to the top dir and deletes empty dirs'
|
|
18
21
|
'seqcheck:Finds missing sequence number'
|
|
19
22
|
'qdir:Sequentially runs all *.sh files in a folder'
|
|
23
|
+
|
|
20
24
|
'dlaudio: yt-dlp best audio'
|
|
21
25
|
'dlvideo: yt-dlp best video'
|
|
26
|
+
|
|
22
27
|
'unemoji:Removes emojis from filenames'
|
|
23
28
|
'rmcover:Removes cover art'
|
|
29
|
+
|
|
24
30
|
'curltime:Measures request response timings'
|
|
25
31
|
)
|
|
26
32
|
|
package/README.md
CHANGED
|
@@ -13,45 +13,51 @@ npx mediasnacks <command> <args>
|
|
|
13
13
|
### Commands
|
|
14
14
|
- `avif` Converts images to AVIF
|
|
15
15
|
- `sqcrop` Square crops images
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
- `resize` Resizes videos or images
|
|
18
19
|
- `edgespic` Extracts first and last frames
|
|
19
|
-
- `framediff`: Plays a video of adjacent frames diff
|
|
20
20
|
- `gif`: Video to GIF
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
- `dropdups` Removes duplicate frames in a video
|
|
24
|
+
- `framediff`: Plays a video of adjacent frames diff
|
|
21
25
|
- `hev1tohvc1`: Fixes video thumbnails not rendering in macOS Finder
|
|
22
26
|
- `moov2front` Rearranges .mov and .mp4 metadata for fast-start streaming
|
|
23
|
-
- `resize` Resizes videos or images
|
|
24
27
|
- `vconcat`: Concatenates videos
|
|
25
28
|
- `vdiff`: Plays a video with the difference of two videos
|
|
26
29
|
- `vsplit`: Splits a video into multiple clips from CSV timestamps
|
|
27
30
|
- `vtrim`: Trims video from start to end time
|
|
28
31
|
|
|
32
|
+
|
|
29
33
|
- `flattendir`: Moves unique files to the top dir and deletes empty dirs
|
|
30
34
|
- `qdir` Sequentially runs all *.sh files in a folder
|
|
31
35
|
- `seqcheck` Finds missing sequence number
|
|
32
36
|
|
|
37
|
+
|
|
33
38
|
- `dlaudio`: yt-dlp best audio
|
|
34
39
|
- `dlvideo`: yt-dlp best video
|
|
35
40
|
|
|
41
|
+
|
|
36
42
|
- `unemoji`: Removes emojis from filenames
|
|
37
43
|
- `rmcover`: Removes cover art
|
|
38
44
|
|
|
45
|
+
|
|
39
46
|
- `curltime`: Measures request response timings
|
|
40
47
|
|
|
41
48
|
### Globs
|
|
42
|
-
Glob patterns are expanded by Node.js
|
|
49
|
+
Glob patterns are expanded by Node.js.
|
|
43
50
|
|
|
44
51
|
```shell
|
|
45
|
-
|
|
46
|
-
|
|
52
|
+
mediasnacks avif file[234].png
|
|
53
|
+
# Expands to: file2.png, file3.png, file4.png
|
|
47
54
|
```
|
|
48
55
|
|
|
49
56
|
```shell
|
|
50
|
-
|
|
51
|
-
|
|
57
|
+
mediasnacks avif -- file[234].png
|
|
58
|
+
# Literal filename: "file[234].png"
|
|
52
59
|
```
|
|
53
60
|
|
|
54
|
-
<br/>
|
|
55
61
|
|
|
56
62
|
---
|
|
57
63
|
|
|
@@ -59,7 +65,7 @@ npx mediasnacks avif -- file[234].png
|
|
|
59
65
|
|
|
60
66
|
### Converting Images to AVIF
|
|
61
67
|
```shell
|
|
62
|
-
|
|
68
|
+
mediasnacks avif [-y | --overwrite] [--output-dir=<dir>] <images>
|
|
63
69
|
```
|
|
64
70
|
|
|
65
71
|
<br/>
|
|
@@ -72,17 +78,17 @@ Resizes videos and images. The aspect ratio is preserved when only one dimension
|
|
|
72
78
|
- `-2` same as `-1` but rounds to the nearest even number
|
|
73
79
|
|
|
74
80
|
```shell
|
|
75
|
-
|
|
81
|
+
mediasnacks resize [--width=<num>] [--height=<num>] [-y | --overwrite] [--output-dir=<dir>] <files>
|
|
76
82
|
```
|
|
77
83
|
|
|
78
84
|
Example: Overwrites the input file (-y)
|
|
79
85
|
```shell
|
|
80
|
-
|
|
86
|
+
mediasnacks resize -y --width 480 'dir-a/**/*.png' 'dir-b/**/*.mp4'
|
|
81
87
|
```
|
|
82
88
|
|
|
83
89
|
Example: Output directory (-o)
|
|
84
90
|
```shell
|
|
85
|
-
|
|
91
|
+
mediasnacks resize --height 240 --output-dir /tmp/out video.mov
|
|
86
92
|
```
|
|
87
93
|
|
|
88
94
|
<br/>
|
|
@@ -93,7 +99,7 @@ Rearranges .mov and .mp4 metadata to the start of the file for fast-start stream
|
|
|
93
99
|
**Files are overwritten**
|
|
94
100
|
|
|
95
101
|
```shell
|
|
96
|
-
|
|
102
|
+
mediasnacks moov2front <videos>
|
|
97
103
|
```
|
|
98
104
|
What is Fast Start?
|
|
99
105
|
- https://wiki.avblocks.com/avblocks-for-cpp/muxer-parameters/mp4
|
|
@@ -109,7 +115,6 @@ What is Fast Start?
|
|
|
109
115
|
|
|
110
116
|

|
|
111
117
|
|
|
112
|
-
|
|
113
118
|
For example, for `dropdups -n2 file.mov`
|
|
114
119
|
|
|
115
120
|
- Open Automator
|
package/package.json
CHANGED
package/src/avif.js
CHANGED
|
@@ -8,7 +8,7 @@ import { ffmpeg, assertUserHasFFmpeg } from './utils/ffmpeg.js'
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
const USAGE = `
|
|
11
|
-
Usage:
|
|
11
|
+
Usage: mediasnacks avif [-y | --overwrite] [--output-dir=<dir>] <images>
|
|
12
12
|
|
|
13
13
|
Converts images to AVIF.
|
|
14
14
|
`.trim()
|
package/src/cli.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import { join } from 'node:path'
|
|
4
|
+
import { styleText } from 'node:util'
|
|
4
5
|
import { spawn } from 'node:child_process'
|
|
5
6
|
import pkgJSON from '../package.json' with { type: 'json' }
|
|
6
7
|
|
|
@@ -9,13 +10,14 @@ const COMMANDS = {
|
|
|
9
10
|
avif: ['avif.js', 'Converts images to AVIF'],
|
|
10
11
|
sqcrop: ['sqcrop.js', 'Square crops images\n'],
|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
resize: ['resize.js', 'Resizes videos or images'],
|
|
13
14
|
edgespic: ['edgespic.js', 'Extracts first and last frames'],
|
|
15
|
+
gif: ['gif.sh', 'Video to GIF\n'],
|
|
16
|
+
|
|
17
|
+
dropdups: ['dropdups.js', 'Removes duplicate frames in a video'],
|
|
14
18
|
framediff: ['framediff.sh', 'Plays a video of adjacent frames diff'],
|
|
15
|
-
gif: ['gif.sh', 'Video to GIF'],
|
|
16
19
|
hev1tohvc1: ['hev1tohvc1.js', 'Fixes video thumbnails not rendering in macOS Finder '],
|
|
17
20
|
moov2front: ['moov2front.js', 'Rearranges .mov and .mp4 metadata for fast-start streaming'],
|
|
18
|
-
resize: ['resize.js', 'Resizes videos or images'],
|
|
19
21
|
vconcat: ['vconcat.sh', 'Concatenates videos'],
|
|
20
22
|
vdiff: ['vdiff.sh', 'Plays a video with the difference of two videos'],
|
|
21
23
|
vsplit: ['vsplit.js', 'Splits a video into multiple clips from CSV timestamps'],
|
|
@@ -39,7 +41,7 @@ Usage: mediasnacks <command> <args>
|
|
|
39
41
|
|
|
40
42
|
Commands:
|
|
41
43
|
${Object.entries(COMMANDS).map(([cmd, [, title]]) =>
|
|
42
|
-
` ${cmd.padEnd(12, ' ')}\t${title}`).join('\n')}
|
|
44
|
+
` ${styleText('bold', cmd.padEnd(12, ' '))}\t${title}`).join('\n')}
|
|
43
45
|
`.trim()
|
|
44
46
|
|
|
45
47
|
|
package/src/dropdups.js
CHANGED
package/src/edgespic.js
CHANGED
|
@@ -8,7 +8,7 @@ import { ffmpeg, videoAttrs, assertUserHasFFmpeg } from './utils/ffmpeg.js'
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
const USAGE = `
|
|
11
|
-
Usage:
|
|
11
|
+
Usage: mediasnacks edgespic [--width=<num>] <files>
|
|
12
12
|
|
|
13
13
|
Extracts the first and last frames from each video and saves them to the 'edgepics/' subfolder.
|
|
14
14
|
--width defaults to 640px and The aspect ratio is preserved.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { test } from 'node:test'
|
|
2
|
+
import { deepEqual } from 'node:assert/strict'
|
|
3
|
+
import { readdirSync } from 'node:fs'
|
|
4
|
+
|
|
5
|
+
import { mkTempDir, cli, dir, touch } from './utils/test-utils.js'
|
|
6
|
+
|
|
7
|
+
test('flattendir moves files to top level and deletes empty dirs', () => {
|
|
8
|
+
const tmp = mkTempDir('flattendir')
|
|
9
|
+
dir(tmp, 'dir1', 'dir1-1')
|
|
10
|
+
dir(tmp, 'dir2')
|
|
11
|
+
touch(tmp, 'file1.txt')
|
|
12
|
+
touch(tmp, 'dir1', 'file2.txt')
|
|
13
|
+
touch(tmp, 'dir1', 'dir1-1', 'file3.txt')
|
|
14
|
+
touch(tmp, 'dir1', '.DS_Store')
|
|
15
|
+
|
|
16
|
+
cli('flattendir', tmp)
|
|
17
|
+
deepEqual(readdirSync(tmp).sort(), [
|
|
18
|
+
'file1.txt',
|
|
19
|
+
'file2.txt',
|
|
20
|
+
'file3.txt'
|
|
21
|
+
])
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
test('flattendir does not move files if filename collision occurs', () => {
|
|
25
|
+
const tmp = mkTempDir('flattendir-collision')
|
|
26
|
+
dir(tmp, 'dir1')
|
|
27
|
+
touch(tmp, 'file1.txt')
|
|
28
|
+
touch(tmp, 'dir1', 'file1.txt')
|
|
29
|
+
|
|
30
|
+
cli('flattendir', tmp)
|
|
31
|
+
deepEqual(readdirSync(tmp, { recursive: true }).sort(), [
|
|
32
|
+
'dir1',
|
|
33
|
+
'dir1/file1.txt',
|
|
34
|
+
'file1.txt'
|
|
35
|
+
])
|
|
36
|
+
})
|
package/src/hev1tohvc1.js
CHANGED
|
@@ -6,7 +6,7 @@ import { videoAttrs, ffmpeg, assertUserHasFFmpeg } from './utils/ffmpeg.js'
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
const USAGE = `
|
|
9
|
-
Usage:
|
|
9
|
+
Usage: mediasnacks hev1tohvc1 <videos>
|
|
10
10
|
|
|
11
11
|
This program fixes video thumbnails not rendering in macOS
|
|
12
12
|
Finder, and fixes video not importable in Final Cut Pro. That’s done
|
package/src/moov2front.js
CHANGED
package/src/qdir.js
CHANGED
|
@@ -3,14 +3,13 @@
|
|
|
3
3
|
import { join } from 'node:path'
|
|
4
4
|
import { spawn } from 'node:child_process'
|
|
5
5
|
import { parseArgs } from 'node:util'
|
|
6
|
-
import { fileURLToPath } from 'node:url'
|
|
7
6
|
import { readdir, writeFile, unlink, rename } from 'node:fs/promises'
|
|
8
7
|
|
|
9
8
|
import { isFile } from './utils/fs-utils.js'
|
|
10
9
|
|
|
11
10
|
|
|
12
11
|
const USAGE = `
|
|
13
|
-
Usage:
|
|
12
|
+
Usage: mediasnacks qdir [folder]
|
|
14
13
|
|
|
15
14
|
Sequentially runs all *.sh files in a folder (cwd by default).
|
|
16
15
|
`.trim()
|
package/src/resize.js
CHANGED
|
@@ -10,7 +10,7 @@ import { ffmpeg, videoAttrs, assertUserHasFFmpeg } from './utils/ffmpeg.js'
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
const USAGE = `
|
|
13
|
-
Usage:
|
|
13
|
+
Usage: mediasnacks resize [--width=<num>] [--height=<num>] [-y | --overwrite] [--output-dir=<dir>] <files>
|
|
14
14
|
|
|
15
15
|
Resizes videos and images. The aspect ratio is preserved when only one dimension is specified.
|
|
16
16
|
|
package/src/seqcheck.js
CHANGED
|
@@ -2,11 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
import { parseArgs } from 'node:util'
|
|
4
4
|
import { readdirSync } from 'node:fs'
|
|
5
|
-
import { fileURLToPath } from 'node:url'
|
|
6
5
|
|
|
7
6
|
|
|
8
7
|
const USAGE = `
|
|
9
|
-
Usage:
|
|
8
|
+
Usage: mediasnacks seqcheck [options] [folder]
|
|
10
9
|
|
|
11
10
|
Find missing numbered files in a sequence.
|
|
12
11
|
|
package/src/sqcrop.js
CHANGED
|
@@ -9,7 +9,7 @@ import { parseOptions } from './utils/parseOptions.js'
|
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
const USAGE = `
|
|
12
|
-
Usage:
|
|
12
|
+
Usage: mediasnacks sqcrop [-y | --overwrite] [--output-dir=<dir>] <images>
|
|
13
13
|
|
|
14
14
|
Square crops images
|
|
15
15
|
`.trim()
|
package/src/unemoji.sh
CHANGED
|
@@ -17,6 +17,9 @@ find . -depth | while IFS= read -r file; do
|
|
|
17
17
|
s/[\x{1FA70}-\x{1FAFF}]//g; # Symbols and Pictographs Extended-A
|
|
18
18
|
s/[\x{1F1E6}-\x{1F1FF}]//g; # Regional Indicator Symbols
|
|
19
19
|
')
|
|
20
|
+
|
|
21
|
+
# Normalize
|
|
22
|
+
newbase=$(printf '%s' "$newbase" | perl -CSD -MUnicode::Normalize -pe '$_ = NFKC($_)')
|
|
20
23
|
|
|
21
24
|
if [ "$base" != "$newbase" ]; then
|
|
22
25
|
newpath="$dir/$newbase"
|
package/src/utils/test-utils.js
CHANGED
|
@@ -2,7 +2,7 @@ import { join } from 'node:path'
|
|
|
2
2
|
import { tmpdir } from 'node:os'
|
|
3
3
|
import { spawnSync } from 'node:child_process'
|
|
4
4
|
import { createHash } from 'node:crypto'
|
|
5
|
-
import { mkdtempSync, readFileSync } from 'node:fs'
|
|
5
|
+
import { mkdtempSync, readFileSync, mkdirSync, writeFileSync } from 'node:fs'
|
|
6
6
|
|
|
7
7
|
const rel = f => join(import.meta.dirname, f)
|
|
8
8
|
|
|
@@ -19,3 +19,12 @@ export function sha1(filePath) {
|
|
|
19
19
|
.update(readFileSync(filePath))
|
|
20
20
|
.digest('base64')
|
|
21
21
|
}
|
|
22
|
+
|
|
23
|
+
export function dir(...args) {
|
|
24
|
+
return mkdirSync(join(...args), { recursive: true })
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function touch(...args) {
|
|
28
|
+
return writeFileSync(join(...args), '')
|
|
29
|
+
}
|
|
30
|
+
|
package/src/vsplit.js
CHANGED
|
@@ -10,7 +10,7 @@ import { assertUserHasFFmpeg, run } from './utils/ffmpeg.js'
|
|
|
10
10
|
// TODO looks like it's missing a frame (perhaps becaue of -c copy)
|
|
11
11
|
|
|
12
12
|
const USAGE = `
|
|
13
|
-
Usage:
|
|
13
|
+
Usage: mediasnacks vsplit <csv> <video>
|
|
14
14
|
|
|
15
15
|
Splits a video into multiple clips from CSV timestamps.
|
|
16
16
|
|