動画ファイルの基本
動画ファイルとは
そもそも動画ファイルの構造はどうなってるのよという話。全ての基本なので今更感もあるのだけど、ここをわかっていないとffmpegは使いづらいので書いてみる。図で表すとこんな感じ。
大雑把に言えば、映像と音声をコンテナが包んでいる感じ*1。普段見慣れているflvとかaviとかmovとかいったファイル形式の多くはコンテナの種類だったわけですね*2。
動画ファイル内部では映像と音声は互いに独立していて、コンテナがメタ情報として同期情報を持っているので、普通に再生すれば映像と音声が合っていても、ふとした拍子にズレてしまうのは映像と音声の間で同期が取れなくなってしまうことが原因(だと思う)。逆に、映像と音声が独立しているからこそ、動画ファイルから映像だけ抜き出す、とかBGMだけ取ってくるというのが簡単にできるわけですね。
なお、コンテナはコンテナの上に載せることのできる映像や音声の形式を選びます。例えば、MP4コンテナにwmv形式の映像は載せられません*3。従って、映像や音声の形式を変換する際にはその形式を受け入れ可能なコンテナを選択する必要があります。逆に、複数の形式のコンテナが対応している映像形式の場合は無劣化でファイル形式(=コンテナ形式)を変換することが可能です。
また、コンテナには必ずしも映像・音声の両方を入れなければならないというわけではなく、例えば、かつて Ogg/Vorbis と言われた Vorbis 形式では、コンテナがOgg、音声はVorbisですが映像データは含まれません。
コーデックとはなんぞや
コーデックとは COder/DECoder の頭文字が原義だそうです。つまり、なにがしかのモノを別の形に変換するためのアルゴリズムのことですね。
もともとの、と言うと何が元なのかわかりにくいので、例えばDVカメラで撮ったムービーをパソコン上でノンリニア編集することを考えてみます。DVカメラからパソコンに取り込んだ映像と音声は、計約27Mbpsです。秒間27Mbit、すなわち一秒間あたり約3.3MB必要なわけです。10分間なら2GB弱ですね。
さすがにいくらHDDが安くなり、光ファイバ早いよねといっても、これだけのデータ量を持つファイルを他のファイルと同じように扱うには無理があります。そこで、何らかの手段を使って、このムービーファイルを破綻なくより扱いやすいサイズにまで減量してやらねばなりません。そこで活躍するのがこのコーデックたちな訳です。既にお気づきかと思いますが、上で映像・音声について〜形式といっていたものの正体ですね。
有名どころを挙げると、映像ではwmv、H.264、DivX、Xvid、theora、Mpeg-4、Mpeg-2、flv*4、音声ではmp3、flac、vorbis、wma、atracなどがあります。なお、 Template:圧縮フォーマット - Wikipedia にはコンテナの形式、映像コーデック、音声コーデックが見やすく纏まっているので、理解の一助になるでしょう。
ffmpegとは
一応本題。
ffmpegとはなんぞや、と言うと、簡潔に言えば「現状よく使われているコンテナ/映像/音声それぞれの形式を変換できるソフト」です*1。最近流通しているものであれば、十中八九対応しているはず。映像コーデックだけ変えたい、とか、コンテナを…とか、でもコマンド一発。最近流行のmov/H.264/AACでも無問題。コマンド一発。
内部的には、一部のコーデック*2については各種ライブラリをリンクすることでエンコード/デコード処理を行っており、それ以外のコーデック形式については自前処理のようです。開発は相当速いスピードで進んでいるようで、コンパイルオプションが変わることもしばしば。そのため、特定の版のコンパイル済みバイナリは公式配布しないという姿勢がとられています*3。
動画編集の際、コンテナ形式、映像コーデック、音声コーデックそれぞれで形式変換を行いたい場合、ffmpegが一本あれば十分に間に合います。既に他の動画変換ソフト使ってるよ、という人も多いと思いますが、各コンテナ/コーデック形式に合わせて実装するのが面倒くさい*4ため、実際には巷に溢れる動画変換と銘打ったソフトの数多くが実処理をffmpegに丸投げしていることが多いです*5。逆に言うと、ffmpegがコマンドラインベースな為に使いにくいのであれば、既に大量にあるGUIフロントエンドとなるソフトを選べばいいのです。例えば MediaCoder とか。
Windows Mediaについて
ffmpeg が対応しているWindows Media系フォーマットは wmv1/wmav1, wmv2/wmav2, wmv3 の三種類あり、前二つはエンコード/デコード対応、wmv3についてはデコードのみ対応しています。
この理由についてはよくわからないのですが、wmv として広く流通している、いわゆるWindows Media 9(VC-1)は wmv3 であり、現状では ffmpeg が対応していない以上、 Windows Media 形式に変換するには ffmpeg では不向きであり、公式のエンコーダーを使うのが無難です。
コマンドラインからffmpegを使ってみる
バイナリ
とりあえずバイナリがなければ話にならないので、適当にHDDの中を探してみるか、グーグル先生に尋ねてみましょう。
もしなければ、 FFmpegダウンロード お気に入りの動画を携帯で見よう からダウンロードさせてもらいましょう。定期的にffmpegの最新版をSVNからチェックアウトしてコンパイル・配布してくれています。携帯動画変換君に付属しているものを使っても良いのですが、如何せんビルド日時が古く*1、新たにダウンロードし直した方がいいかと。
ダウンロードしたアーカイブを解凍し、適当なフォルダに移動します。可能ならパスの通ったフォルダ(C:\windows とか)にコピーするのが望ましい。
尚、最近の配布分については3G携帯向けlibamrは含まれていません。非GPLなコードが使われているようなので、再配布禁止になってしまったようです。詳しくは:
FFmpeg rev.11662 ダウンロード お気に入りの動画を携帯で見よう
http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/2008-January/040059.html
H.264/AACに変換
とりあえず、何かしら適当なムービーファイルを用意しましょう。なければ適当に一般公開されているようなムービーをネットから持ってきましょう。後述しますが、最新版のffmpegでは、特にコーデック指定形式が大幅に変わっているので古い文献はほとんど役に立ちません。
あたりは押さえておく必要があります。
例えば、shunirr.org の中の人が書いていたように、wmv/wma 形式の wmv ファイルをH.264/AAC形式のmovファイルに2-pass encodingで変換するには、スタートメニューからファイル名を指定して実行を開き、cmdと打ち込んでコマンドプロンプトを開きます。そこに
ffmpeg -i hoge.wmv -vcodec libx264 -vb 400k -acodec libfaac -ac 2 -ar 48000 -ab 64k -pass 2 fuga.mp4
を打ち込みます。これで一発。 -vb は映像側ビットレートの指定なので、高画質でエンコードしたいなら適当な数字に置換してやればOK。
対応形式とコマンドのお話
基本的には出力形式を指定してやれば、入力コーデック形式についてはファイルのFour CC*2を利用してほぼ自動で判別してくれるようです。ただし、コンテナの形式に限っては、入力時、出力時に指定された拡張子を基に判断する模様*3。
対応コンテナ/コーデック形式は
ffmpeg -formats
で表示が可能です。が、随分多いので
ffmpeg -formats > format.txt
として外部ファイルに出力してやった方が見やすいです。Cygwin入ってるなら |less でもおk。
この出力内容は大きく二つに分かれており、
File formats:
が対応コンテナ(ファイルフォーマット)の種類、
Codecs:
が映像/音声コーデックの種類を表します。
頭に DEVSDT とかいろいろ並んでいますが、最初3文字の意味は
- D
- デコード可能(変換元として入力対応)
- E
- エンコード可能(変換先として出力可能)
- V
- ビデオ(映像)
- A
- オーディオ(音声)
ですので、ここから目的のコーデックが対応しているかどうか、および引数指定時のコーデック名称をチェックします。
例えばH.264の場合は
D V DT h264
なのでビデオフォーマットとしてデコード可能、ただしエンコードは不可、となります。一方、libx264では
EV libx264
ですので、ビデオフォーマットとしてでコード可能、ただしデコードは不可、となります*4。
これはAAC、mp3でも同じで、デコード時は
D A mpeg4aac D A mp3
ですがエンコード時には
EA libfaac EA libmp3lame
で対応されます。
flv+mp3に変換したいなら、
ffmpeg -i hoge.wmv -vcodec flv -vb 400k -acodec libmp3lame -ab 128k -pass 2 fuga.flv
とかで変換可能。
映像/音声の一方だけ変換するため、コーデックを変換する必要がない場合は、
-vcodec copy -acodec copy
で変換元ファイルの形式がそのまま引き継がれます。