我有大约 70 个 mp4 文件,我想直接提取音频文件而无需进一步转码。所有 mp4 文件都有 aac 音频文件。
我知道我可以使用以下命令从其中一个 mp4 文件中提取音频文件:
avconv -i "INPUT FILE" -map 0:1 -c:a copy "OUTPUT FILE"
我如何从所有 70 个 mp4 文件中提取所有音频文件,以便最终得到 70 个 aac 文件?
答案1
您可以使用一个简单的 for 循环:
for i in *.mp4; do
avconv -i "${i}" -map 0:1 -c:a copy "${i%.mp4}.aac"
done
或者在一行中:
for i in *.mp4; do avconv -i "${i}" -map 0:1 -c:a copy "${i%.mp4}.aac"; done
它所做的是avconv
针对每个名为 like 的文件运行一次,*.mp4
其中文件名存储在${i}
变量中。
${i%.mp4}
意思是${i}
(即文件名).mp4
从末尾剥离。
答案2
如果您将所有文件都放在一个目录中,那么 Xiao 的回答通常是最有用的;但如果有 MP4 文件分散在不同的目录中,则可以使用此find
命令将它们全部转换。
find . -type f -name '*.mp4' -exec bash -c 'avconv -i "$0" -c:a copy "${0/%mp4/m4a}"' {} \;
这在末尾使用了略有不同的 bash 字符串替换形式:“${0/%mp4/m4a}”告诉 bash 用 m4a 替换 mp4,但前提是 mp4 位于字符串的末尾。
答案3
为了避免同时处理多个文件(这可能会占用过多资源),请使用parallel
。默认情况下,它一次只执行一项任务。如果您想并行使用多个 CPU 核心,请尝试parallel -j 4 ...
并行执行 4 项任务。另请查看man parallel
。
sudo apt-get install parallel
此行将从aac
选定的视频中提取音频文件并将其放入m4a
容器中。
parallel avconv -i '{}' -map 0:1 -c:a copy '{.}.m4a' ::: %F
直接在 CLI 中工作时,%F
用输入文件列表替换。例如*.mp4
。
灵感来自这答案,由先前的答案这个问题,邪恶汤对后者的评论(说:“原始 aac 文件不能包含元数据;如果您想保留原始文件中的元数据,请使用 m4a(这只是 mp4 的另一个名称,但被音频播放器广泛认可)而不是 aac 作为文件扩展名”)。
我在 Thunar 自定义操作中使用了这样的命令,
将应用程序限制为包含aac
音频的视频。
为了在处理过程中打开一个终端窗口,并在结束时关闭,可以如下更改命令:
gnome-terminal -e "parallel avconv -i '{}' -map 0:1 -c:a copy '{.}.m4a' ::: %F"
答案4
我扩展了@Xiao-Long Chen 的答案,将其变成一个脚本,当输出文件较新时跳过文件:
#!/bin/bash
for file in *.mp4; do
OUT="${file/.mp4/.m4a}"
if [ "$file" == "$OUT" ]; then
echo "Unable to handle $file" >&2
exit 1
fi
if [ "$OUT" -nt "$file" ]; then
echo "Skipping $file; output file is newer."
continue
fi
echo "Converting \"$file\" -> \"$OUT\""
avconv -loglevel warning -i "$file" -map 0:1 -c:a copy "$OUT"
done