mediasnacks 0.26.0 → 0.28.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/index.js +4 -0
- package/package.json +1 -1
- package/src/avif.js +17 -29
- package/src/cli.js +18 -21
- package/src/countframes.js +10 -19
- package/src/detectdups.js +10 -17
- package/src/dlaudio.js +34 -0
- package/src/dlvideo.js +28 -0
- package/src/dropdups.js +6 -16
- package/src/edgespic.js +11 -19
- package/src/frameseq.js +13 -21
- package/src/gif.js +43 -0
- package/src/hev1tohvc1.js +10 -21
- package/src/moov2front.js +10 -24
- package/src/openrand.js +4 -10
- package/src/play.js +4 -10
- package/src/png.js +30 -0
- package/src/prores.js +10 -17
- package/src/qdir.js +3 -11
- package/src/resize.js +29 -43
- package/src/seqcheck.js +7 -17
- package/src/sqcrop.js +18 -29
- package/src/ssim.js +4 -12
- package/src/unemoji.js +69 -0
- package/src/utils/fs-utils.js +1 -1
- package/src/utils/parseOptions.js +15 -2
- package/src/utils/subprocess.js +2 -1
- package/src/utils/videoAttrs.js +2 -2
- package/src/vsplit.js +8 -17
- package/src/vtrim.js +7 -15
- package/src/dlaudio.sh +0 -4
- package/src/dlvideo.sh +0 -4
- package/src/gif.sh +0 -44
- package/src/png.sh +0 -20
- package/src/unemoji.sh +0 -30
package/src/vsplit.js
CHANGED
|
@@ -2,7 +2,7 @@ import { readFileSync } from 'node:fs'
|
|
|
2
2
|
import { resolve, parse, join } from 'node:path'
|
|
3
3
|
|
|
4
4
|
import { parseOptions } from './utils/parseOptions.js'
|
|
5
|
-
import {
|
|
5
|
+
import { run } from './utils/subprocess.js'
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
// TODO looks like it's missing a frame (perhaps becaue of -c copy)
|
|
@@ -31,29 +31,20 @@ EXAMPLE
|
|
|
31
31
|
|
|
32
32
|
SEE ALSO
|
|
33
33
|
mediasnacks vtrim
|
|
34
|
-
|
|
34
|
+
`
|
|
35
35
|
|
|
36
36
|
|
|
37
37
|
export default async function main() {
|
|
38
|
-
await
|
|
39
|
-
|
|
40
|
-
const { values, files } = await parseOptions({
|
|
41
|
-
help: { short: 'h', type: 'boolean' },
|
|
42
|
-
})
|
|
43
|
-
|
|
44
|
-
if (values.help) {
|
|
45
|
-
console.log(HELP)
|
|
46
|
-
return
|
|
47
|
-
}
|
|
38
|
+
const { values, files } = await parseOptions(HELP)
|
|
48
39
|
|
|
49
40
|
if (files.length !== 2)
|
|
50
|
-
throw
|
|
41
|
+
throw 'Expected 2 arguments: CSV file and video file.'
|
|
51
42
|
|
|
52
43
|
const [csvPath, videoPath] = files.map(f => resolve(f))
|
|
53
44
|
|
|
54
45
|
const clips = parseCSV(csvPath)
|
|
55
46
|
if (!clips.length)
|
|
56
|
-
throw
|
|
47
|
+
throw 'CSV file contains no clips'
|
|
57
48
|
|
|
58
49
|
console.log(`Splitting video into ${clips.length} clip${clips.length === 1 ? '' : 's'}…`)
|
|
59
50
|
await vsplit(videoPath, clips)
|
|
@@ -64,14 +55,14 @@ function parseCSV(csvPath) {
|
|
|
64
55
|
const lines = content.split('\n').filter(line => line.trim())
|
|
65
56
|
|
|
66
57
|
if (!lines.length)
|
|
67
|
-
throw
|
|
58
|
+
throw 'CSV file is empty'
|
|
68
59
|
|
|
69
60
|
const clips = []
|
|
70
61
|
for (let i = 1; i < lines.length; i++) { // unconditionally skips header
|
|
71
62
|
const parts = lines[i].split(',').map(s => s.trim())
|
|
72
63
|
|
|
73
64
|
if (parts.length !== 2)
|
|
74
|
-
throw
|
|
65
|
+
throw `Invalid CSV format at line ${i + 1}: expected 2 columns, got ${parts.length}`
|
|
75
66
|
|
|
76
67
|
clips.push(parts)
|
|
77
68
|
}
|
|
@@ -80,7 +71,7 @@ function parseCSV(csvPath) {
|
|
|
80
71
|
|
|
81
72
|
export async function vsplit(videoPath, clips) {
|
|
82
73
|
const { dir, name, ext } = parse(videoPath)
|
|
83
|
-
const seqLen =
|
|
74
|
+
const seqLen = String(clips.length).length
|
|
84
75
|
|
|
85
76
|
for (let i = 0; i < clips.length; i++) {
|
|
86
77
|
const [start, end] = clips[i]
|
package/src/vtrim.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { resolve, parse } from 'node:path'
|
|
2
2
|
import { parseOptions } from './utils/parseOptions.js'
|
|
3
|
-
import { ffmpeg
|
|
3
|
+
import { ffmpeg } from './utils/subprocess.js'
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
const HELP = `
|
|
7
7
|
SYNOPSIS
|
|
8
|
-
mediasnacks vtrim [
|
|
8
|
+
mediasnacks vtrim [options] <videos>
|
|
9
9
|
|
|
10
10
|
DESCRIPTION
|
|
11
11
|
Trims a video without re-encoding (fast, but approximate cuts).
|
|
@@ -16,25 +16,17 @@ OPTIONS
|
|
|
16
16
|
|
|
17
17
|
SEE ALSO
|
|
18
18
|
mediasnacks vsplit
|
|
19
|
-
|
|
19
|
+
`
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
export default async function main() {
|
|
23
|
-
await
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
start: { short: 's', type: 'string', default: '' },
|
|
27
|
-
end: { short: 'e', type: 'string', default: '' },
|
|
28
|
-
help: { short: 'h', type: 'boolean' }
|
|
23
|
+
const { values, files } = await parseOptions(HELP, {
|
|
24
|
+
start: { short: 's', type: 'string' },
|
|
25
|
+
end: { short: 'e', type: 'string' },
|
|
29
26
|
})
|
|
30
27
|
|
|
31
|
-
if (values.help) {
|
|
32
|
-
console.log(HELP)
|
|
33
|
-
return
|
|
34
|
-
}
|
|
35
|
-
|
|
36
28
|
if (!files.length)
|
|
37
|
-
throw
|
|
29
|
+
throw 'No video specified.'
|
|
38
30
|
|
|
39
31
|
for (const file of files)
|
|
40
32
|
await vtrim({
|
package/src/dlaudio.sh
DELETED
package/src/dlvideo.sh
DELETED
package/src/gif.sh
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
#!/bin/sh
|
|
2
|
-
|
|
3
|
-
FPS=10
|
|
4
|
-
WIDTH=600
|
|
5
|
-
|
|
6
|
-
help() {
|
|
7
|
-
/bin/cat << EOF
|
|
8
|
-
SYNOPSIS
|
|
9
|
-
mediasnacks gif [--fps <number>] [-w | --width <pixels>] <file>
|
|
10
|
-
|
|
11
|
-
DESCRIPTION
|
|
12
|
-
Converts video to GIF
|
|
13
|
-
|
|
14
|
-
OPTIONS
|
|
15
|
-
--fps Default: $FPS
|
|
16
|
-
-w,--width Default: $WIDTH
|
|
17
|
-
EOF
|
|
18
|
-
exit "${1:-0}"
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
while [ $# -gt 0 ]; do
|
|
22
|
-
case "$1" in
|
|
23
|
-
--fps)
|
|
24
|
-
FPS="$2";
|
|
25
|
-
shift 2 ;;
|
|
26
|
-
|
|
27
|
-
--width|-w)
|
|
28
|
-
WIDTH="$2"
|
|
29
|
-
shift 2 ;;
|
|
30
|
-
|
|
31
|
-
--help|-h)
|
|
32
|
-
help ;;
|
|
33
|
-
|
|
34
|
-
*)
|
|
35
|
-
file="$1"
|
|
36
|
-
shift ;;
|
|
37
|
-
esac
|
|
38
|
-
done
|
|
39
|
-
|
|
40
|
-
[ -z "$file" ] && help 1
|
|
41
|
-
|
|
42
|
-
ffmpeg -v error -i "$file" \
|
|
43
|
-
-vf "fps=${FPS},scale=${WIDTH}:-1" \
|
|
44
|
-
"${file%.*}.gif"
|
package/src/png.sh
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
#!/bin/sh
|
|
2
|
-
|
|
3
|
-
help() {
|
|
4
|
-
/bin/cat << EOF
|
|
5
|
-
SYNOPSIS
|
|
6
|
-
mediasnacks png <img1> [img2 ...]
|
|
7
|
-
|
|
8
|
-
DESCRIPTION
|
|
9
|
-
Losslessly optimizes PNG images with oxipng at max level.
|
|
10
|
-
|
|
11
|
-
EXAMPLE
|
|
12
|
-
mediasnacks png *.png
|
|
13
|
-
EOF
|
|
14
|
-
exit "${1:-0}"
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
[ "$1" = "-h" ] && help
|
|
18
|
-
[ $# -eq 0 ] && help 1
|
|
19
|
-
|
|
20
|
-
oxipng --opt max "$@"
|
package/src/unemoji.sh
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
#!/bin/sh
|
|
2
|
-
|
|
3
|
-
# Removes emoji's from filenames on the current working directory.
|
|
4
|
-
# Does not overwrite files.
|
|
5
|
-
|
|
6
|
-
find . -depth | while IFS= read -r file; do
|
|
7
|
-
dir=$(dirname "$file")
|
|
8
|
-
base=$(basename "$file")
|
|
9
|
-
|
|
10
|
-
# Remove Emojis
|
|
11
|
-
newbase=$(printf '%s' "$base" | perl -CSD -pe '
|
|
12
|
-
s/[\x{1F600}-\x{1F64F}]//g; # Emoticons
|
|
13
|
-
s/[\x{1F300}-\x{1F5FF}]//g; # Misc Symbols and Pictographs
|
|
14
|
-
s/[\x{1F680}-\x{1F6FF}]//g; # Transport and Map
|
|
15
|
-
s/[\x{2600}-\x{26FF}]//g; # Misc symbols
|
|
16
|
-
s/[\x{2700}-\x{27BF}]//g; # Dingbats
|
|
17
|
-
s/[\x{1F900}-\x{1F9FF}]//g; # Supplemental Symbols and Pictographs
|
|
18
|
-
s/[\x{1FA70}-\x{1FAFF}]//g; # Symbols and Pictographs Extended-A
|
|
19
|
-
s/[\x{1F1E6}-\x{1F1FF}]//g; # Regional Indicator Symbols
|
|
20
|
-
')
|
|
21
|
-
|
|
22
|
-
# Normalize to Unicode NFKC
|
|
23
|
-
newbase=$(printf '%s' "$newbase" | perl -CSD -MUnicode::Normalize -pe '$_ = NFKC($_)')
|
|
24
|
-
|
|
25
|
-
if [ "$base" != "$newbase" ]; then
|
|
26
|
-
newpath="$dir/$newbase"
|
|
27
|
-
echo "Renaming: $file -> $newpath"
|
|
28
|
-
mv -n "$file" "$newpath"
|
|
29
|
-
fi
|
|
30
|
-
done
|