tangled
alpha
login
or
join now
matrixfurry.com
/
scripts
1
fork
atom
Various scripts that I maintain
1
fork
atom
overview
issues
pulls
pipelines
extract-m4a (new script)
matrixfurry.com
7 months ago
7f256cb8
9dafa890
verified
This commit was signed with the committer's
known signature
.
matrixfurry.com
SSH Key Fingerprint:
SHA256:68a4335QUqf4PR8E4jmNMaKH1SIxm7r+LLY9m/8nc/s=
+88
1 changed file
expand all
collapse all
unified
split
scripts
extract-m4a.nu
+88
scripts/extract-m4a.nu
···
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
···
1
+
#!/usr/bin/env nu
2
+
# SPDX-License-Identifier: AGPL-3.0-only
3
+
# Copyright (c) 2025 Shiloh Fen <shiloh@shilohfen.com>
4
+
5
+
use std log
6
+
7
+
# Extract audio from a m4a file to the codec's native container
8
+
def main [
9
+
path: path
10
+
--rm # Remove the original file after conversion
11
+
] {
12
+
let path = $path | path expand
13
+
14
+
match (ls -D $path).0.type {
15
+
"dir" => {
16
+
let files = ls $path
17
+
| get name
18
+
| where $it ends-with ".m4a"
19
+
20
+
let files_len = $files | length
21
+
22
+
log info $"Extracting ($files_len) files."
23
+
$files | par-each {|file|
24
+
extract-file $file
25
+
if $rm {rm $file}
26
+
}
27
+
log info $"Extracted ($files_len) files."
28
+
}
29
+
"file" => {
30
+
extract-file $path
31
+
if $rm {rm $path}
32
+
}
33
+
_ => (error make {
34
+
msg: "Invalid path"
35
+
label: {
36
+
text: $"Invalid path: ($path)"
37
+
span: (metadata $path).span
38
+
}
39
+
})
40
+
}
41
+
}
42
+
43
+
def extract-file [file: path] {
44
+
let file = $file | path expand
45
+
let parsed_path = $file | path parse
46
+
47
+
log info $"Extracting `($file)`"
48
+
49
+
if $parsed_path.extension != "m4a" {
50
+
error make {
51
+
msg: "Format not supported"
52
+
label: {
53
+
text: $"Unsupported format: \"($parsed_path.extension)\""
54
+
span: (metadata $file).span
55
+
}
56
+
help: "This tool currently only supports M4A."
57
+
}
58
+
}
59
+
60
+
let codec = ffprobe -v quiet -select_streams a -show_entries stream=codec_name -of csv=p=0 $file | split row ","
61
+
# Args:
62
+
# -v quiet -> Only print result
63
+
# -select_streams a -> Select only audio streams, in case there is album artwork or a video embedded as a stream
64
+
# -show_entries stream=codec_name -> Get codec
65
+
# -of csv=p=0 -> print comma-seperated list with no headers
66
+
67
+
if ($codec | length) > 1 {
68
+
error make {
69
+
msg: "Too many audio streams"
70
+
label: {
71
+
text: $"Contains more than 1 audio stream: ($codec | length)"
72
+
span: (metadata $file).span
73
+
}
74
+
help: "This tool can currently only handle a single audio stream"
75
+
}
76
+
}
77
+
78
+
let codec = $codec.0
79
+
80
+
let output: path = $"($parsed_path.parent)/($parsed_path.stem).($codec)"
81
+
82
+
ffmpeg -v quiet -i $file -c:a copy -vn $output
83
+
# Args:
84
+
# -c:a copy -> Copy codec
85
+
# -vn -> No video
86
+
87
+
log info $"Extracted `($file)` to `($output)`"
88
+
}