如何在不解压的情况下使用ffmpeg从mp4文件中批量提取音频(自动音频编解码器检测)?


19

我有228个mp4文件(2.6 GB),并希望从其中提取音频(mp3或ogg)。我想批量提取它们-最好使用bash。我不确定是否所有文件都使用与2006年至2012年不同年份记录的音频编解码器相同的音频。

我想遍历所有这些,选择文件名,检测音频编解码器,并使用ffmpeg提取音频。

可能吗?


这是一个脚本问题,因此与Ubuntu无关。这里不是话题,但是SO或unix.SE可能是一个更好的地方。
Mahesh 2012年

谢谢。下次,我将尝试在更合适的位置提出这样的问题。
wryrych

Answers:


28

您说要“从它们中提取音频(mp3或ogg)”。但是,如果mp4文件中的音频不是其中之一,该怎么办?您仍然必须进行转码。那么,为什么不将音频格式检测留给ffmpeg呢?

要转换一个文件:

ffmpeg -i videofile.mp4 -vn -acodec libvorbis audiofile.ogg

要转换许多文件:

for vid in *.mp4; do ffmpeg -i "$vid" -vn -acodec libvorbis "${vid%.mp4}.ogg"; done

当然,您可以选择所需的任何ffmpeg参数进行音频编码,以设置比特率等。

使用-acodec libmp3lame扩展名并将其从.ogg更改.mp3为mp3编码。

如果您想要真正提取音频,则可以使用将音频轨道“复制”到文件中-acodec copy。当然,主要的区别是转码速度很慢且占用大量CPU,而复制却很快,因为您只是将字节从一个文件移到另一个文件。以下是仅复制音轨的方法(假设它为mp3格式):

ffmpeg -i videofile.mp4 -vn -acodec copy audiofile.mp3

请注意,在这种情况下,音频文件格式必须与容器的格式一致(即,如果音频为AAC格式,则必须说audiofile.aac)。您可以使用该ffprobe命令查看所使用的编解码器,这可能会提供一些信息:

ffprobe -v error -select_streams a:0 -show_entries stream=codec_name -print_format csv=p=0 "videofile.mp4"

自动解析音频编解码器并相应地命名音频文件的一种可能方法是:

mkdir -p output
# current directory has to contain at least one .mp4 file 
for vid in *.mp4; do
   codec="$(ffprobe -v error -select_streams a:0 -show_entries stream=codec_name -print_format csv=p=0 "$vid")"
   case "$codec" in
    mp3    ) filetype=mp3 ;;
    vorbis ) filetype=ogg ;;
    *      ) filetype= ;;
   esac

   if [ "$filetype" ]; then 
    ffmpeg -i "$vid" -vn -acodec copy output/"${vid%.*}"."$filetype"
   else
    ffmpeg -i "$vid" -vn -acodec libvorbis output/"${vid%.*}".ogg
done

注意:输出文件是output在开头创建的子目录中创建的(如有必要)。对于mp3和vorbis以外的其他编解码器,它将音频转换为ogg。Ubuntu 14.04在标准存储库中没有ffmpeg,但是您可以添加ppa:mc3man / trusty-media存储库并安装ffmpeg软件包以获取所需的软件。有关详细信息,请参见此处


我说错了。我想要mp3或ogg,但是正如您所注意到的,音频编解码器有所不同-在此示例中为aac。所以无论如何我都必须对它们进行转码。非常感谢您的帮助!
wryrych

您的automagic示例中断了其中包含空格的文件名,因为您未在ffprobe子语句中引用$ file。更改为:* mp4 * avi中的文件;ffmpeg -i“ $ file” -vn -acodec复制“ $ file”。ffprobe "$file" 2>&1 |sed -rn 's/.*Audio: (...), .*/\1/p'; 完成修复。
Andrew Beals

+1,但此答案似乎可以使用更新:This program is only provided for compatibility and will be removed in a future release. Please use avconv instead.
Nicolas Raoul

ffmpegffprobe不适用于Ubuntu 14.04或更高版本。
jarno

1
@jarno实际版本ffmpeg 在15.04中返回到Ubuntu,它看起来像Libav谷壳avconv在15.10中avprobe已被删除
llogan

1

正如Nicolas Raoul所说,这需要更新。这是roadmr给出的同一行,但改用avconv:

for vid in *.mp4; do avconv -i "$vid" "${vid%.mp4}.mp3"; done


现在已经过时了。FFmpeg又回来了,而Libav走了。
llogan

完全正确。如果有人认为ffmpeg快要死了,请阅读以下内容:en.wikipedia.org/wiki/Libav#Confusion
Scooby-2
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.