我大约有70个mp4文件,我想直接提取音频文件而无需进一步进行转码。所有的mp4文件都有aac音频文件。
我了解我可以使用以下命令从mp4文件之一提取音频文件:
avconv -i "INPUT FILE" -map 0:1 -c:a copy "OUTPUT FILE"
如何从所有70个mp4文件中提取所有音频文件,所以最终得到70个aac文件?
我大约有70个mp4文件,我想直接提取音频文件而无需进一步进行转码。所有的mp4文件都有aac音频文件。
我了解我可以使用以下命令从mp4文件之一提取音频文件:
avconv -i "INPUT FILE" -map 0:1 -c:a copy "OUTPUT FILE"
如何从所有70个mp4文件中提取所有音频文件,所以最终得到70个aac文件?
Answers:
您可以使用简单的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
对每个命名*.mp4
文件(文件名存储在${i}
变量中的位置)运行一次。
${i%.mp4}
意味着${i}
(即文件名).mp4
从结尾处剥离。
bash /path/to/the/script %F
-像这里
-map
如果切换到其他输出格式(如果该格式可以同时包含音频和视频),则丢弃仍可能会导致视频被视为视频。保持原样更安全。
如果您将所有文件都放在一个目录中,则肖的答案通常是最有用的。但是,如果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在字符串的末尾。
%
,它将替换它找到的字符串的第一个实例;您还可以使用#
使其仅在变量开头的字符串来代替;因此$ {0 / mp4 / m4a}将用m4a替换mp4的第一个实例(如果您的文件名确实很奇怪,可能会出现问题);$ {0 /#mp4 / m4a}和$ {0 /#mp4 / m4a}会将mp4替换为m4a,但前提是变量的字符串值以mp4开头(显然在这里没有用,但在其他地方可能会派上用场)。
为避免同时处理多个文件(可能会使用太多资源),请使用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
。
灵感来自这个答案,前面的回答这个问题,并通过evilsoup “后者(话说的评论:”原始的AAC文件不能包含元数据;如果你想保留元数据从原来的文件,然后使用M4A(其只是mp4的另一个名称,但在音频播放器中已得到相当广泛的认可),而不是aac作为文件扩展名')。
我在Thunar自定义操作中使用了此类命令,
将应用程序限制为包含aac
音频的视频。
要在处理过程中打开一个终端窗口,并在最后关闭,可以像下面这样更改命令:
gnome-terminal -e "parallel avconv -i '{}' -map 0:1 -c:a copy '{.}.m4a' ::: %F"
我扩展了@ 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