FFmpeg

Last-modified: 2010-09-09 (木) 18:05:04

macで使う

macportsにてstableのパッケージが提供されている。
macportsの使い方はMac#r6ab7864を参照。

sudo install ffmpeg

でOK。コーデックなどをいっきにインストールしてくれる。

動画早回し

  • 目標:音声と動画の整合性をとりつつ、任意のcodec、任意の解像度・・・の動画ファイルを処理する。
    もちろん、音声のピッチが高くなったりしてはいけない。
  • 画質・音質の劣化には目をつぶる。
  • 処理時間もとりあえず潤沢にあると仮定する。余りに遅いようであれば、ファイル形式の変換だけをかけてQuickTimeで早回し設定で見ればいい。

オーソドックな方法

元動画から動画と音声を生データに分離し、それぞれのレート(フレームレート、サンプリングレート)を同じだけ倍にする。具体的にはffmpegの分析データをgrepで抽出し、それを処理する。

  • 分離
    ffmpeg -i input.avi output.yuv output.wav
    問題点:出力ファイルがめちゃくちゃ重い。コンバート事態も遅い
  • 合体
    • 動画
      • r optionで元のフレームレート(fps)*2を指定。(本来)小数指定してはいけないことに注意(分数で処理するから)。
      • s optionで元の動画のサイズを指定
      • b optionで指定するビットレートは、かなり大きい値にしなければいけないようだ(要検証)元の動画の分析結果から自動的に定めるのが望ましい。
  • 音声
    • ar optionでフレームレートの変化と同じだけ変える。 これだとピッチが上がってコエガタカクナッテシマウので、次のようにsoxコマンドを使う。
      macなら port install sox で入手できた。携帯動画変換君が使いたければ、http://sourceforge.net/projects/sox/files/から最新版の実行ファイルをダウンロードすればいい
      sox input.wav output.wav tempo [-q:高速処理用] [-m|-s|-l : for music|for speech|linear] 1.5
      1.5のところが実際の速度(x倍)。そのあとに、[segment [search [overlap]]]というオプションを指定できるが、-mや-sを使うと自動計算される。音楽がメインで、それを短縮するといったケースは稀であろうから、-sオプションの決め打ちでよかろう。(有意な差はみられない)

結論

Mac OS X上で動かすシェルスクリプトはつぎのようになる。windowsならscreenを決め打ちして携帯動画変換君にいれればいいだろう。もちろんwindowsのバッチファイルや他言語のプログラムで処理してもいいが。
未検証部分もあるので、バグリポートをお願いしたい。
filemoviespeed.sh

問題

上記スクリプトで大容量のファイルを処理するとHDDがパンクする。yuvファイル+wavファイルは、元のファイルのおよそ100倍にまで膨れ上がるので、1GBの動画を処理しようとすると100GBの容量が必要である。

解決策1

時間分割し、部分ごとに処理して最後に統合することでこの問題はある程度回避できると想定されるが、任意長のファイルにどのようにしてこの処理を行うか、つなぎめはシームレスになるかが問題である。

  • ファイルの分割に関係のあるオプション(ffmpeg)
    • -t <duration>
      生成するファイルの時間長さを指定(秒)(hh:mm:ss)
    • -ss <position>
      生成するファイルの、元ファイルにおける起点時間を指定(秒)(hh:mm:ss)
    • -fs <limit_size>
      生成ファイルの大きさ限界を指定

実際の生成ファイルはtの値を少し無視する。音声と映像をセットにして出力した上でくっつけることで、音ズレはさほどおこらないが、つなぎ目で映像が最大数秒止まる。分割数が多くなると見るに耐えないだろう。

  • ファイルの結合
    mencoderを使うのが簡単。mencoderはmplayerに同梱されている。windowsなら検索してダウンロード、macならportでmplayerをいれればいい。
    それぞれの分割ファイルの形式は揃えておくのがよかろう。
    mencoder v1.avi v2.avi v3.avi -o v.avi [-oac copy -ovc copy]
  • ファイルの結合(mpeg)
    MPEG-1形式はそのままファイルを足し合わせることができるコンテナである。
    cat v1.mpg v2.mpg > v.mpg
    で結合可能。ただし、vlcでは時間の表示などがおかしくなる。そこで、結合後のファイルをffmpegで再処理する。
    ffmpeg -i v.mpg -vcodec copy -acodec copy v2.mpg
    ffmpegでmpeg-1形式で出力するには、-f mpegオプションをいれれば大丈夫。

解決策2

mplayerで早回し再生できるなぁとおもって良く調べてみたら、mencoderでこのようなエンコードができることがわかった。ただし、エンコードオプションをうまく指定しないと(うまく指定しても)ところどころ動画が停止することと、標準ではscaletempoフィルタがはいっていないことが問題である。さらに、(すくなくともmplayerにおいては)音質はかなりひどい。1.8倍速ですでに聞くのが困難である(QuickTimeの音質のほうが数倍すぐれている)。くわえて、rc3のmplayerに同梱されているmencoderではこのオプションは有効にならない(指定できるが、反映されていない)。
利点としては一回のエンコードである程度ファイルサイズの小さいものに変換できることがおおきい。シェルスクリプトを書く必要すらない。
大容量ファイルor高速処理が必要なファイルにはこのエンコーダの使用を検討したい。また、通常のビデオ視聴においてもmplayerの使用が検討できる。
例:

mencoder -speed 1.8 01.flv -ovc lavc -vf scale=320:240 -lavcopts vcodec=mpeg4:vbitrate=800 \
-oac mp3lame &color(Red){-af scaletempo}; -srate 44100 -lameopts mode=1:cbr:br=128 -o 01.avi

注意:ビットレートがあってないとエラーにならずに処理が失敗します。

解決策3

以上の解決策に対する問題点から次のような方法が考えられる。この方法はyuvを経由するよりもHDD圧迫がすくなく、さらに(たぶん)速い。

  • 音声の圧縮にはsoxを使う(wavファイルはmp3などにくらべて非常に重いといっても、元の動画ファイルほどに重いはずはないから、HDDの容量圧迫という問題にはいたらないと想定される)
  • 映像の圧縮にはmencoderを使う。圧縮結果の質についてはオプションをうまく調節することでおそらく対処可能。肝心なのはエラーを無視する心。圧縮結果の時間長さはwavファイルの結果と秒単位で一致しているので、ファイル全体のエンコーディングを検討すれば、音ズレの問題は許容範囲となろう。(二時間ぐらいの映像で、口ひとパクぶんずれた)

メモ

  • ffmpeg -i a.vob -vn 1.wav
  • sox 1.wav res.wav tempo -s 1.8
  • ffmpeg -i 1.vob -vcodec copy -an res.mpg
  • mencoder -speed 1.8 res.mpg -vfm ffmpeg -ovc lavc -vf scale720:480 \

    -lavcopts vcodec=mpeg4:vbitrate=7220 -o res.avi 2>/dev/null

  • ffmpeg -i res.avi -i res.wav -b 7220k -vcodec copy -acodec libfaac a.mp4

参考サイト

QuickTime向けに変換する設定

QuickTimeでは任意の倍速(標準では0.1~3.0)で再生できる。音も綺麗で、違和感はかなり少ない。
QuickTimeはmp4形式が標準のようなので、h264,aac,mp4のセットで出力。
ビットレートが選択可能(ビットレート変換を掛ける意味はないが、処理速度を気にする場合は。)
fileTranscoding_PC_Mpeg4_forQT.ini