web-dev-qa-db-ja.com

解凍せずにffmpegでmp4ファイルからオーディオをバッチ抽出するにはどうすればよいですか(自動オーディオコーデック検出)?

228個のmp4ファイル(2.6GB)があり、それらからオーディオを抽出したい(mp3またはogg)。できればbashでバッチ抽出したいです。 2006年から2012年までのさまざまな年に録音されたすべてのファイルが同じオーディオコーデックを使用しているかどうかはわかりません。

それらすべてをループし、ファイル名を選択し、オーディオコーデックを検出し、ffmpegを使用してオーディオを抽出します。

出来ますか?

19
wryrych

「それらからオーディオを抽出する(mp3またはogg)」と言います。しかし、mp4ファイルのオーディオがそれらのいずれでもない場合はどうでしょうか?とにかくトランスコードする必要があります。それでは、オーディオ形式の検出をffmpegに任せてみませんか?

1つのファイルを変換するには:

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を使用し、mp3エンコーディングの拡張子を.oggから.mp3に変更します。

本当にextractオーディオが必要な場合は、-acodec copyを使用してオーディオトラックをファイルに単に「コピー」できます。もちろん、主な違いは、トランスコーディングが遅く、CPUに負荷がかかることです。一方、バイトをあるファイルから別のファイルに移動するだけなので、コピーは非常に高速です。オーディオトラックだけをコピーする方法は次のとおりです(mp3形式であると想定)。

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

この場合、オーディオファイル形式hasは、コンテナの内容と一貫性があることに注意してください(つまり、オーディオが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パッケージをインストールして必要なソフトウェアを取得できます。詳細については、 here を参照してください。

28
roadmr

ニコラスラウルが述べたように、これは更新が必要です。 roadmrが提供したのと同じ行ですが、代わりにavconvを使用しています:

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

1
Scooby-2