mediasnacks 0.29.0 → 0.30.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/README.md +1 -0
- package/index.js +1 -0
- package/package.json +1 -1
- package/src/base64.js +42 -0
- package/src/cli.js +2 -1
- package/src/moov2front.js +4 -6
- package/src/play.sh +10 -0
- package/src/qdir.js +3 -3
- package/src/utils/mimeFor.js +21 -0
package/README.md
CHANGED
package/index.js
CHANGED
package/package.json
CHANGED
package/src/base64.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs'
|
|
2
|
+
import { parseOptions } from './utils/parseOptions.js'
|
|
3
|
+
import { mimeFor } from './utils/mimeFor.js'
|
|
4
|
+
|
|
5
|
+
const HELP = `
|
|
6
|
+
SYNOPSIS
|
|
7
|
+
mediasnacks base64 [--css | --img] file
|
|
8
|
+
|
|
9
|
+
DESCRIPTION
|
|
10
|
+
Encodes a file to data URI.
|
|
11
|
+
|
|
12
|
+
EXAMPLES
|
|
13
|
+
mediasnacks base64 file
|
|
14
|
+
mediasnacks base64 --img file
|
|
15
|
+
mediasnacks base64 --css file
|
|
16
|
+
`
|
|
17
|
+
|
|
18
|
+
export default async function main() {
|
|
19
|
+
const { values, files } = await parseOptions(HELP, {
|
|
20
|
+
css: { type: 'boolean' },
|
|
21
|
+
img: { type: 'boolean' },
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
if (files.length !== 1)
|
|
25
|
+
throw 'Only one file is accepted'
|
|
26
|
+
|
|
27
|
+
const { data, mime } = await base64(files[0])
|
|
28
|
+
|
|
29
|
+
if (values.css)
|
|
30
|
+
console.log(`background-image: url(data:${mime};base64,${data})`)
|
|
31
|
+
else if (values.img)
|
|
32
|
+
console.log(`<img src="data:${mime};base64,${data}" />`)
|
|
33
|
+
else
|
|
34
|
+
console.log(data)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export async function base64(filePath) {
|
|
38
|
+
return {
|
|
39
|
+
data: readFileSync(filePath).toString('base64'),
|
|
40
|
+
mime: await mimeFor(filePath)
|
|
41
|
+
}
|
|
42
|
+
}
|
package/src/cli.js
CHANGED
|
@@ -9,7 +9,8 @@ import pkgJSON from '../package.json' with { type: 'json' }
|
|
|
9
9
|
const COMMANDS = {
|
|
10
10
|
avif: ['./avif.js', 'Converts images to AVIF'],
|
|
11
11
|
png: ['./png.js', 'Optimizes PNG images with oxipng'],
|
|
12
|
-
sqcrop: ['./sqcrop.js', 'Square crops images
|
|
12
|
+
sqcrop: ['./sqcrop.js', 'Square crops images'],
|
|
13
|
+
base64: ['./base64.js', 'Encodes a file to data URI\n'],
|
|
13
14
|
|
|
14
15
|
resize: ['./resize.js', 'Resizes videos or images'],
|
|
15
16
|
edgespic: ['./edgespic.js', 'Extracts first and last frames'],
|
package/src/moov2front.js
CHANGED
|
@@ -9,13 +9,11 @@ SYNOPSIS
|
|
|
9
9
|
|
|
10
10
|
DESCRIPTION
|
|
11
11
|
Rearranges .mov and .mp4 metadata to the start of the file for fast-start streaming.
|
|
12
|
-
|
|
13
|
-
What is Fast Start?
|
|
14
|
-
- https://wiki.avblocks.com/avblocks-for-cpp/muxer-parameters/mp4
|
|
15
|
-
- https://trac.ffmpeg.org/wiki/HowToCheckIfFaststartIsEnabledForPlayback
|
|
16
|
-
|
|
17
|
-
NOTES
|
|
18
12
|
Files are overwritten.
|
|
13
|
+
|
|
14
|
+
SEE ALSO
|
|
15
|
+
- https://wiki.avblocks.com/avblocks-for-cpp/muxer-parameters/mp4
|
|
16
|
+
- https://trac.ffmpeg.org/wiki/HowToCheckIfFaststartIsEnabledForPlayback
|
|
19
17
|
`
|
|
20
18
|
|
|
21
19
|
export default async function main() {
|
package/src/play.sh
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
|
|
3
|
+
# mpv with a filtered playlist with recursive search
|
|
4
|
+
# usage: cd Music && play artistA artistB
|
|
5
|
+
|
|
6
|
+
regex=$(IFS='|'; echo "$*")
|
|
7
|
+
/usr/bin/find -E . -type f -iregex ".*(${regex}).*" \
|
|
8
|
+
-not -path "*.fcpbundle/*" \
|
|
9
|
+
-not -name ".DS_Store" \
|
|
10
|
+
-print | mpv --playlist=-
|
package/src/qdir.js
CHANGED
|
@@ -68,8 +68,8 @@ export async function qdir(dir, pollIntervalMs = 10_000) {
|
|
|
68
68
|
async function getNextJob(dir) {
|
|
69
69
|
const entries = await readdir(dir, { withFileTypes: true })
|
|
70
70
|
const scripts = entries
|
|
71
|
-
.filter(
|
|
72
|
-
.map(
|
|
71
|
+
.filter(dirent => dirent.isFile() && filter(dirent.name))
|
|
72
|
+
.map(dirent => dirent.name)
|
|
73
73
|
.sort()
|
|
74
74
|
return scripts.length
|
|
75
75
|
? join(dir, scripts[0])
|
|
@@ -81,7 +81,7 @@ async function runShell(scriptPath) {
|
|
|
81
81
|
return new Promise((resolve, reject) => {
|
|
82
82
|
const p = spawn('/bin/sh', [scriptPath], { stdio: 'inherit' })
|
|
83
83
|
p.on('error', reject)
|
|
84
|
-
p.on('exit',
|
|
84
|
+
p.on('exit', resolve)
|
|
85
85
|
})
|
|
86
86
|
}
|
|
87
87
|
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { parse } from 'node:path'
|
|
2
|
+
import { runSilently } from './subprocess.js'
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
export async function mimeFor(filePath) {
|
|
6
|
+
return process.platform === 'win32'
|
|
7
|
+
? await windowsMime(filePath)
|
|
8
|
+
: (await runSilently('file', ['--mime-type', '--brief', filePath])).stdout.trim()
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
async function windowsMime(filePath) { // TODO test on windows
|
|
12
|
+
const ext = parse(filePath).ext.toLowerCase()
|
|
13
|
+
try {
|
|
14
|
+
const { stdout } = await runSilently('reg', ['query', `HKEY_CLASSES_ROOT\\${ext}`, '/v', 'Content Type'])
|
|
15
|
+
const match = stdout.match(/Content Type\s+REG_SZ\s+(\S+)/)
|
|
16
|
+
if (match)
|
|
17
|
+
return match[1]
|
|
18
|
+
}
|
|
19
|
+
catch {}
|
|
20
|
+
return 'application/octet-stream'
|
|
21
|
+
}
|