本人是音乐人,兼职会编程,能力有限,请见谅
有时我需要多个音频文件的 LUFS 级别,而最快的方法(对我来说......)是使用 ffmpeg 来计算它,因为它会在几秒钟内离线处理一个文件,而不必全部播放在 DAW 中进行读数的方式。
这是我想出的剧本:
#!/bin/zsh
TempDirectory="~/Desktop/TEMP"
TempRAW="$TempDirectory/ffmpeg_LUFS_output_RAW.txt"
OutputCSV="$TempDirectory/ffmpeg_LUFS_output.csv"
for CurrentFile in "$@"
do
echo "File: "$(/usr/bin/basename "$CurrentFile") >>"$TempRAW"
/opt/homebrew/bin/ffmpeg -i "$CurrentFile" -hide_banner -af ebur128=framelog=verbose -f null - 2>>"$TempRAW"
done
# The next part extracts the info from the raw ffmpeg output file
# The output from ffmpeg is 55 lines
# Line 1: File: LSK Adore v18 [Dreamy] MIX ALL Stereo.wav
# ... snip ...
# Line 47: Integrated loudness:
# Line 48: I: -32.2 LUFS
# Line 49: Threshold: -42.6 LUFS
#
# The lines that interest me are Line 1 + 48:
while IFS= read -r line
do
if [[ "$line" =~ ^"File: " ]]; then
printf "$line," | sed 's/File: //' >>"$OutputCSV"
fi
if [[ "$line" =~ ^" I:" ]]; then
echo "$line" | sed 's/ I: //'>>"$OutputCSV"
fi
done < "$TempRAW"
有效,我的问题解决了,我的能力如何让我解决了它。
但我宁愿不必写临时文件。
写这篇文章时,我至少搜索了 4 个小时来寻找解决方案。他们中的大多数人解释说要使用 awk 处理存储在变量中的 ffmpeg 输出。但是 awk 总是会为第一个条目创建双倍的结果(我可能做错了什么......)。
没有临时文件我怎么写这个?
这里是输出的更多示例行:
File: LSK Adore v18 [Dreamy] MIX ALL Stereo.wav
Guessed Channel Layout for Input Stream #0.0 : stereo
Input #0, wav, from '/Volumes/Project HDD/Leopard Skin/Themes/Bounces/LSK Adore v18 STEMS 78bpm/LSK Adore v18 [Dreamy] MIX ALL Stereo.wav':
Metadata:
encoded_by : Logic Pro X
originator_reference: aaO3N!Fzk7Rk
date : 2021-05-24
creation_time : 18:48:28
time_reference : 276258449
...
SNIP
...
size= 0kB time=00:00:00.00 bitrate=N/A speed=N/A
size=N/A time=00:01:49.21 bitrate=N/A speed= 766x
video:0kB audio:20481kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
[Parsed_ebur128_0 @ 0x153f0af90] Summary:
Integrated loudness:
I: -32.2 LUFS
Threshold: -42.6 LUFS
Loudness range:
LRA: 4.9 LU
Threshold: -52.7 LUFS
LRA low: -34.5 LUFS
LRA high: -29.6 LUFS
您可以将输出通过管道传输到
sed
,并让它过滤第一行(1p
),以及包含“综合响度”(/Integrated loudness/{n;p}
)的行下面的行:
ffmpeg -i "$CurrentFile" … 2>&1 | sed -n '1p;/Integrated loudness/{n;p}'
File: LSK Adore v18 [Dreamy] MIX ALL Stereo.wav
I: -32.2 LUFS
你真正需要的概念只是 unix 管道 (
|
):
for CurrentFile in "$@"
do
echo $(/usr/bin/basename "$CurrentFile") >>"$OutputCSV"
/opt/homebrew/bin/ffmpeg -i "$CurrentFile" -hide_banner -af ebur128=framelog=verbose -f null - |&
while IFS= read -r line
do
if [[ "$line" =~ ^" I:" ]]; then
echo "$line" | sed 's/ I: //'>>"$OutputCSV"
fi
done
done
这可以用一个循环来完成。一种方法是:
for CurrentFile in "$@"; do
printf '%s,' "${CurrentFile##*/}"
ffmpeg -i "$CurrentFile" -hide_banner -af ebur128=framelog=verbose -f null - 2> >(sed -n 's/^[[:blank:]]*I:[[:blank:]]*//p')
done > "$OutputCSV"
假设:
^File:<white space>
和<white_space>I:<white_space>
一个
awk
想法:
awk '{ if (match($0,/^File:[[:space:]]*|^.[[:space:]]*I:[[:space:]]*/)) print substr($0,RSTART+RLENGTH) }'
地点:
^File:[[:space:]]*
或^.[[:space:]]*I:[[:space:]]*
match(...)
返回一个非零值然后...substr($0,RSTART+RLENGTH)
提取匹配后出现的那部分行(RSTART
和 RLENGTH
由成功的 match(...)
设置)OP 然后可以通过以下两种方法之一将
ffmpeg
输出提供给此命令:
ffmpeg ... | awk '{ .... }'
# or
awk '{ .... }' < <(ffmpeg ...)
使用本地文件模拟OP的
ffmpeg
输出:
$ cat ffmpeg.out
File: LSK Adore v18 [Dreamy] MIX ALL Stereo.wav
Guessed Channel Layout for Input Stream #0.0 : stereo
Input #0, wav, from '/Volumes/Project HDD/Leopard Skin/Themes/Bounces/LSK Adore v18 STEMS 78bpm/LSK Adore v18 [Dreamy] MIX ALL Stereo.wav':
Metadata:
encoded_by : Logic Pro X
originator_reference: aaO3N!Fzk7Rk
date : 2021-05-24
creation_time : 18:48:28
time_reference : 276258449
...
SNIP
...
size= 0kB time=00:00:00.00 bitrate=N/A speed=N/A
size=N/A time=00:01:49.21 bitrate=N/A speed= 766x
video:0kB audio:20481kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
[Parsed_ebur128_0 @ 0x153f0af90] Summary:
Integrated loudness:
I: -32.2 LUFS
Threshold: -42.6 LUFS
Loudness range:
LRA: 4.9 LU
Threshold: -52.7 LUFS
LRA low: -34.5 LUFS
LRA high: -29.6 LUFS
通过
awk
代码运行:
$ cat ffmpeg.out | awk '{ if (match($0,/^File:[[:space:]]*|^.[[:space:]]*I:[[:space:]]*/)) print substr($0,RSTART+RLENGTH) }'
LSK Adore v18 [Dreamy] MIX ALL Stereo.wav
-32.2 LUFS
或者我们可以将
awk
脚本放在一个文件中:
$ cat ffmpeg.awk
{ if (match($0,/^File:[[:space:]]*|^.[[:space:]]*I:[[:space:]]*/)) print substr($0,RSTART+RLENGTH) }
调用变成:
$ cat ffmpeg.out | awk -f ffmpeg.awk
LSK Adore v18 [Dreamy] MIX ALL Stereo.wav
-32.2 LUFS