動画から音声を抽出したり、マニュアルで別々にエンコードしたビデオとオーディオを多重化したりすることは人口の10%くらいの人にはよくあることだと思います。そんなときにまず使われるFFmpegですが、今のFFmpegについてストリームやメタデータも含めて書いた日本語のドキュメントは少ないんじゃないかと思わなくもなかったりします。そこで、FFmpegのオプション指定について備忘録的に書き残しておきます。
動画コンテナ
ファイルフォーマットですが、今は動画と音声が両方MPEG系(MPEG-2、MPEG-4、H.264、H.265;MP3、AACなど)ならMP4、いずれかが異なる変態系ならMKV (Matroska)でいいんじゃないかと勝手に思っています。macOSでもMKVのサムネイル表示やプレビューに対応してほしいですね。放送系ならMPEG-2 TSもありますが… うん、触れるのはやめとこう。
[追記 2020/03/19] MP4コンテナにMPEG-2 videoを入れるのはダメかも。Wikipediaで見たんだけどQuickTime Playerで再生できない…
ファイル情報を調べる
動画を扱いたかったら、まずは敵(動画ファイル)を知ることです。ストリーム番号とかなんやねん!となりがちですので。以下のコマンドで入力ファイルの情報を調べることができます。
ffmpeg -i input.mp4
出力ファイルがないお!と怒られるのが嫌な人はffprobe
を使いましょう。別ソフトですが、MediaInfoも便利です。
オプションについて
あまり言われていませんが、オプションの順番は重要です。基本的には、オプションは直近の後続する(入出力)ファイルに掛かります。
demuxする
demux(demultiplex:分離)とは、複数のストリームをもつ動画ファイルを別々にすることです。以下のコマンドは入力ファイルの音声を抽出(Extract)します。
ffmpeg -i input.mp4 -vn -c copy output.mp4
-vn
でビデオを無効化することで音声ファイルのみにしています。-an
とすると、反対に無音の動画だけを取り出すことができます。-c
は-codec
の略記で、copy
を指定することで再エンコードなし(無劣化)でコンテナの入れ替えだけを可能にしています。-c:a
(オーディオストリーム)や-c:v
(ビデオストリーム)で明示的に指定するのもいいと思います。-c:0
(0番目のストリーム)のようにストリーム番号(普通、ビデオが0でオーディオが1)で指定することもできます。出力フォーマットは、出力ファイルの拡張子からFFmpegが勝手に判断してくれるので特に指定せずでOKです。
ちなみに、オーディオのみの場合わかりやすいように.m4aも使われますが、これはAppleが勝手に決めたやつらしいです。(たぶん)ファイルフォーマット的には変わりません。
-map
について
ストリームをマニュアルで指定することもできます。
ffmpeg -i input.mp4 -map 0:1 -c copy output.mp4
以上のようにすると0番目の入力ファイルの1番目のストリームを出力することになるので、上と大体一緒です。-map 0:0
とすればビデオのみになります。入力ファイル番号があるということは、お察しの通り次のmuxでも使えます。
muxする
mux(multiplex:多重化、結合)とは動画や音声など複数のストリームを一つにすることです。
ffmpeg -i video.mp4 -i audio.mp4 -map_metadata 0 -c copy output.mp4
こんなんでいいんじゃないでしょうか。
-map_metadata
について
動画のメタデータ(作成日時やタグなど)を保持したい場合もあると思います。-map_metadata 0
は-map_metadata 0:g
の略記で、0番目の入力ファイルのグローバルメタデータ(ファイル全体に適用されるメタデータ)を出力ファイルに付加することを指定しています。大抵の場合、0
(つまり、ビデオのグローバルメタデータ)でやりたいようにいくんじゃないでしょうか。g
の他にはs
(ストリーム)、c
(チャプター)、p
(プログラム)があります。フルに記法を使うと-map_metadata:s:a 0:g
なんてこともでき、ややこしいので説明すると、0番目の入力ファイルのグローバルメタデータを出力ファイルの(全ての)オーディオストリームに付加することを表しています。
MP4Boxについて
実はFFmpegの作るMP4は信用できなかったりするらしいのですが(驚愕)、
MP4Boxの作るMP4はMacのFinderでサムネイルが表示されないので私はFFmpegとともに生きていくことに決めました。
再生できないファイル
メタデータやファイルフォーマットが変になっている関係で再生できないファイルはそのまま出力することで大抵うまくいきます。
ffmpeg -i input.mp4 -c copy output.mp4
おわりに
-c:v codec
や-c:a codec
(指定できるcodec
はffmpeg -codecs
で見られます)でできるエンコードは闇なのでガチ勢に譲ります。