マソム自宅サーバ構築の記録
- ■
-
FFmpegを使ってみる
-
作成日:08/04/07
更新日:09/08/07
前置き
各種動画をFlash用のビデオファイル形式 FLV にプログラムで自動変換したい。出来れば携帯用の3GPPや3GPP2にも。と探してFFmpegがあることを知りました。
インストールを済ませたので、コマンドラインから使ってみたいと思います。
以下を参考にさせて頂きました。有り難うございます。
Vine Linux への FFmpeg インストールと、使い方
まちがいだらけの FFmpegドキュメンテーション
OS X(10.4)で、ffmpegを使い、flvを生成
ffmpegの最新リビジョンはWMV9のデコードが出来るみたいですね
最新ffmpegの高度なオプション
FFmpegで変換した3GPP動画をNTTドコモiモーションのストリーミング再生に対応させる (for Linux)
MP4Boxの主要コマンド
変換してみるフォーマット
以下の変換を試してみます。
1.mpeg --> FLV
2.WMV --> FLV
3.3gpp --> FLV
4.FLV --> 3gpp
5.FLV --> mpg4
6.mov --> FLV
なお、変換元ファイルはWindowsに付いていたサンプル、ネットで拾ってきたもの、その他色々です。
mpg を FLV へ変換
まずは、オプション等は指定せず変換してみます。
$ ffmpeg -i test_mpg.mpg -vcodec flv test_mpg.flv
・・・省略・・・
Input #0, mpeg, from 'test_mpg.mpg':
Duration: 00:03:44.8, start: 0.340078, bitrate: 1396 kb/s
Stream #0.0[0x1e0]: Video: mpeg1video, yuv420p, 352x240 [PAR 200:219 DAR 880:657], 1150 kb/s, 29.97 tb(r)
Stream #0.1[0x1c0]: Audio: mp2, 44100 Hz, stereo, 224 kb/s
Output #0, flv, to 'test_mpg.flv':
Stream #0.0: Video: flv, yuv420p, 352x240 [PAR 200:219 DAR 880:657], q=2-31, 200 kb/s, 29.97 tb(c)
Stream #0.1: Audio: libmp3lame, 44100 Hz, stereo, 64 kb/s
Stream mapping:
Stream #0.0 -> #0.0
Stream #0.1 -> #0.1
Press [q] to stop encoding
frame= 6739 fps=252 q=14.0 Lsize= 7787kB time=224.9 bitrate= 283.7kbits/s
video:5790kB audio:1757kB global headers:0kB muxing overhead 3.181438%
サムネイルを作ります。
-s でフレームサイズも指定します。-y で出力ファイルを上書きします。
$ ffmpeg -y -i test_mpg.mpg -f image2 -s 134x90 -ss 00:00:10 -vframes 1 test_mpg.jpg
・・・省略・・・
Input #0, mpeg, from 'test_mpg.mpg':
Duration: 00:03:44.8, start: 0.340078, bitrate: 1396 kb/s
Stream #0.0[0x1e0]: Video: mpeg1video, yuv420p, 352x240 [PAR 200:219 DAR 880:657], 1150 kb/s, 29.97 tb(r)
Stream #0.1[0x1c0]: Audio: mp2, 44100 Hz, stereo, 224 kb/s
PIX_FMT_YUV420P will be used as an intermediate format for rescaling
Output #0, image2, to 'test_mpg.jpg':
Stream #0.0: Video: mjpeg, yuvj420p, 134x90 [PAR 224:249 DAR 15008:11205], q=2-31, 200 kb/s, 29.97 tb(c)
Stream mapping:
Stream #0.0 -> #0.0
Press [q] to stop encoding
frame= 1 fps= 0 q=3.2 Lsize= -0kB time=0.0 bitrate= -5.3kbits/s
video:5kB audio:0kB global headers:0kB muxing overhead -100.442389%
なお、フレーム・サイズは、2の倍数で指定しないと以下のエラーになりました。
Frame size must be a multiple of 2
作成したFLVもjpegも問題なく再生、表示出来ました。
但し、最適なオプション等はこれから確認です。
WMV を FLV へ変換
何もオプションを指定せず変換しようとしたら以下のエラーになりました。。
$ ffmpeg -i test_wmv.wmv -vcodec flv test_wmv.flv
・・・省略・・・
Input #0, asf, from 'test_wmv.wmv':
Duration: 00:00:12.8, start: 5.000000, bitrate: 281 kb/s
Stream #0.0: Audio: wmav2, 32000 Hz, stereo, 32 kb/s
Stream #0.1: Video: wmv3, yuv420p, 320x240, 241 kb/s, 29.97 tb(r)
Output #0, flv, to 'test_wmv.flv':
Stream #0.0: Video: flv, yuv420p, 320x240, q=2-31, 200 kb/s, 29.97 tb(c)
Stream #0.1: Audio: libmp3lame, 32000 Hz, stereo, 64 kb/s
Stream mapping:
Stream #0.1 -> #0.0
Stream #0.0 -> #0.1
[libmp3lame @ 0x55c650]flv does not support that sample rate, choose from (44100, 22050, 11025).
Could not write header for output file #0 (incorrect codec parameters ?)
サンプリングレートの指定が必要なようです。-ar で指定します。
$ ffmpeg -y -i test_wmv.wmv -vcodec flv -ar 22050 test_wmv.flv
・・・省略・・・
Input #0, asf, from 'test_wmv.wmv':
Duration: 00:00:12.8, start: 5.000000, bitrate: 281 kb/s
Stream #0.0: Audio: wmav2, 32000 Hz, stereo, 32 kb/s
Stream #0.1: Video: wmv3, yuv420p, 320x240, 241 kb/s, 29.97 tb(r)
Output #0, flv, to 'test_wmv.flv':
Stream #0.0: Video: flv, yuv420p, 320x240, q=2-31, 200 kb/s, 29.97 tb(c)
Stream #0.1: Audio: libmp3lame, 22050 Hz, stereo, 64 kb/s
Stream mapping:
Stream #0.1 -> #0.0
Stream #0.0 -> #0.1
Press [q] to stop encoding
frame= 378 fps=336 q=12.2 Lsize= 662kB time=12.6 bitrate= 429.8kbits/s
video:62kB audio:100kB global headers:0kB muxing overhead 308.027241%
サムネイルを作ります。
$ ffmpeg -y -i test_wmv.wmv -f image2 -s 134x90 -ss 00:00:05 -vframes 1 test_wmv.jpg
・・・省略・・・
Input #0, asf, from 'test_wmv.wmv':
Duration: 00:00:12.8, start: 5.000000, bitrate: 281 kb/s
Stream #0.0: Audio: wmav2, 32000 Hz, stereo, 32 kb/s
Stream #0.1: Video: wmv3, yuv420p, 320x240, 241 kb/s, 29.97 tb(r)
PIX_FMT_YUV420P will be used as an intermediate format for rescaling
Output #0, image2, to 'test_wmv.jpg':
Stream #0.0: Video: mjpeg, yuvj420p, 134x90, q=2-31, 200 kb/s, 29.97 tb(c)
Stream mapping:
Stream #0.1 -> #0.0
Press [q] to stop encoding
frame= 1 fps= 0 q=2.6 Lsize= -0kB time=0.0 bitrate= -5.3kbits/s
video:4kB audio:0kB global headers:0kB muxing overhead -100.512104%
作成したFLVもjpegも問題なく再生、表示出来ました。
3gpp を FLV へ変換
こちらもサンプリングレートの指定が必要でした。
$ ffmpeg -y -i test_3gp.3gp -vcodec flv -ar 22050 test_3gp.flv
・・・省略・・・
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'test_3gp.3gp':
Duration: 00:03:01.0, start: 0.000000, bitrate: 76 kb/s
Stream #0.0(eng): Video: mpeg4, yuv420p, 240x180 [PAR 1:1 DAR 4:3], 10.00 tb(r)
Stream #0.1(eng): Audio: mpeg4aac, 32000 Hz, stereo
Output #0, flv, to 'test_3gp.flv':
Stream #0.0(eng): Video: flv, yuv420p, 240x180 [PAR 1:1 DAR 4:3], q=2-31, 200 kb/s, 10.00 tb(c)
Stream #0.1(eng): Audio: libmp3lame, 22050 Hz, stereo, 64 kb/s
Stream mapping:
Stream #0.0 -> #0.0
Stream #0.1 -> #0.1
Press [q] to stop encoding
frame= 1810 fps=268 q=2.0 Lsize= 4595kB time=180.7 bitrate= 208.4kbits/s
video:3047kB audio:1411kB global headers:0kB muxing overhead 3.063870%
サムネイルを作ります。
$ ffmpeg -y -i test_3gp.3gp -f image2 -s 134x90 -ss 00:00:05 -vframes 1 test_3gp.jpg
・・・省略・・・
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'test_3gp.3gp':
Duration: 00:03:01.0, start: 0.000000, bitrate: 76 kb/s
Stream #0.0(eng): Video: mpeg4, yuv420p, 240x180 [PAR 1:1 DAR 4:3], 10.00 tb(r)
Stream #0.1(eng): Audio: mpeg4aac, 32000 Hz, stereo
PIX_FMT_YUV420P will be used as an intermediate format for rescaling
Output #0, image2, to 'test_3gp.jpg':
Stream #0.0(eng): Video: mjpeg, yuvj420p, 134x90 [PAR 60:67 DAR 4:3], q=2-31, 200 kb/s, 10.00 tb(c)
Stream mapping:
Stream #0.0 -> #0.0
Press [q] to stop encoding
frame= 1 fps= 0 q=3.3 Lsize= -0kB time=0.1 bitrate= -1.8kbits/s
video:5kB audio:0kB global headers:0kB muxing overhead -100.474138%
作成したFLVもjpegも問題なく再生、表示出来ました。
FLV の一部を切り出して 3gpp へ変換
私は SoftBank の 705SH なので、まずそれで再生が確認できるフォーマットにすることにしました。
こちらを参考にしました。
オプションの指定が色々必要でした。
-flags bitexact : ヘルプには「use only bitexact stuff (except (i)dct)」とあります。圧縮のアルゴリズムに関係があるのかと解釈。
付けていないと携帯で再生できない時は付ければ良いとのことです。今回の検証では指定が必要でした。
-ss : 開始時間。秒又はhh:mm:ss[.xxx]
-t : 記録時間。秒又はhh:mm:ss[.xxx]
-b : ビデオのビットレート。ビット/秒単位
-r : フレームレート
-acodec : 音声コーデックは、AMR-NB にします。
なお、DoCoMo等で使えるAACにしたい時は aac ではなく libfaac と指定が必要でした。
変わったのだそうです。
-ar : オーディオサンプリング周波数
-ab : オーディオビットレート。キロビット/秒単位
-ac : オーディオチャンネル数。モノラルなら 1 です。
$ ffmpeg -y -i test_flv.flv -ss 2 -t 15 -vcodec mpeg4 -b 64k -r 10 -s 176x144 -acodec libamr_nb -ar 8000 -ab 12.2k -ac 1 -flags bitexact test_flv.3gp
・・・省略・・・
Input #0, flv, from 'test_flv.flv':
Duration: 00:07:11.4, start: 0.000000, bitrate: 64 kb/s
Stream #0.0: Video: flv, yuv420p, 600x400, 29.97 tb(r)
Stream #0.1: Audio: mp3, 44100 Hz, mono, 64 kb/s
Output #0, 3gp, to 'test_flv.3gp':
Stream #0.0: Video: mpeg4, yuv420p, 176x144, q=2-31, 64 kb/s, 10.00 tb(c)
Stream #0.1: Audio: libamr_nb, 8000 Hz, mono, 12 kb/s
Stream mapping:
Stream #0.0 -> #0.0
Stream #0.1 -> #0.1
Press [q] to stop encoding
frame= 151 fps= 0 q=4.2 Lsize= 183kB time=15.0 bitrate= 99.9kbits/s
video:155kB audio:24kB global headers:0kB muxing overhead 2.922419%
因みに、再生が出来なかった -flags bitexact を付けない場合の結果ログは以下の通りです。 少し値が違います。
frame= 151 fps= 0 q=4.1 Lsize= 182kB time=15.0 bitrate= 99.2kbits/s
video:153kB audio:24kB global headers:0kB muxing overhead 2.943108%
SoftBank の 705SH でダウンロードし再生できました。
なお、SoftBank の場合は、HTMLでは<a>タグでリンクを付けるだけです。
i-modeで使える3gpp へ変換
残念ながらこのままではdocomoのストリーミング(プログレッシブダウンロード)方式は出来ないのだそうです。
詳しくは
こちらに載っていました。有り難うございます。
その為に、MP4Boxを使います。gpacに付属しているMPEG-4のエンコード、デコード用のツールです。コマンドラインから使えます。
gpacのインストールは
こちらです。
$ MP4Box -add test_flv.3gp -brand mmp4:1 -new test_flv_i.3gp
IsoMedia import - track ID 1 - Video (size 176 x 144)
IsoMedia import - track ID 2 - Audio (SR 8000 - 2 channels)
Converting to 3GP file...
[3GPP convert] Setting major brand to 3GPP V5 file
Saving test_flv_i.3gp: 0.500 secs Interleaving
指定サイズで分割した3gpp へ変換
携帯ムービーはファイルサイズに上限があります。
MP4Boxでファイルを分割出来るそうです。
以下SoftBank用に、300kBで分割してみました。
$ ffmpeg -y -i test_flv.flv -ss 2 -t 90 -vcodec mpeg4 -b 64k -r 10 -s 176x144 -acodec libamr_nb -ar 8000 -ab 12.2k -ac 1 -flags bitexact test_flv.3gp
・・・省略・・・
Input #0, flv, from 'test_flv.flv':
Duration: 00:07:11.4, start: 0.000000, bitrate: 64 kb/s
Stream #0.0: Video: flv, yuv420p, 600x400, 29.97 tb(r)
Stream #0.1: Audio: mp3, 44100 Hz, mono, 64 kb/s
Output #0, 3gp, to 'test_flv.3gp':
Stream #0.0: Video: mpeg4, yuv420p, 176x144, q=2-31, 64 kb/s, 10.00 tb(c)
Stream #0.1: Audio: libamr_nb, 8000 Hz, mono, 12 kb/s
Stream mapping:
Stream #0.0 -> #0.0
Stream #0.1 -> #0.1
Press [q] to stop encoding
frame= 902 fps=168 q=3.2 Lsize= 897kB time=90.0 bitrate= 81.6kbits/s
video:731kB audio:141kB global headers:0kB muxing overhead 2.981127%
$ MP4Box -splits 300 test_flv.3gp
Storing split-file test_flv_001.3gp - duration 23.30 seconds
[3GPP convert] Setting major brand to 3GPP V5 file
Storing split-file test_flv_002.3gp - duration 25.10 seconds
[3GPP convert] Setting major brand to 3GPP V5 file
Storing split-file test_flv_003.3gp - duration 32.10 seconds
[3GPP convert] Setting major brand to 3GPP V5 file
Storing split-file test_flv_004.3gp - duration 9.30 seconds
[3GPP convert] Setting major brand to 3GPP V5 file
mov の一部を切り出して FLV へ変換
アスペクト比の変換も行います。サイズ変更後に、上下に黒帯を追加し、3:2から4:3へ変更します。
$ ffmpeg -y -i otl_pngn.mov -ss 2 -t 60 -vcodec flv -s 480x320 -padtop 20 -padbottom 20 -aspect 4:3 -r 16 -b 360k -acodec libmp3lame -ac 2 -ar 44100 -ab 96k otl_pngn.flv
・・・省略・・・
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'otl_pngn.mov':
Duration: 00:04:33.8, start: 0.000000, bitrate: 45696 kb/s
Stream #0.0(eng): Video: mjpeg, yuvj422p, 720x480 [PAR 72:72 DAR 3:2], 29.97 tb(r)
Stream #0.1(eng): Audio: pcm_s16be, 44100 Hz, stereo, 1411 kb/s
PIX_FMT_YUV420P will be used as an intermediate format for rescaling
Output #0, flv, to 'otl_pngn.flv':
Stream #0.0(eng): Video: flv, yuv420p, 480x360 [PAR 1:1 DAR 4:3], q=2-31, 360 kb/s, 16.00 tb(c)
Stream #0.1(eng): Audio: libmp3lame, 44100 Hz, stereo, 96 kb/s
Stream mapping:
Stream #0.0 -> #0.0
Stream #0.1 -> #0.1
Press [q] to stop encoding
frame= 962 fps= 45 q=4.7 Lsize= 3578kB time=60.1 bitrate= 487.5kbits/s
video:2810kB audio:716kB global headers:0kB muxing overhead 1.470208%
動画情報の取得
動画情報を表示するだけ。
$ ffmpeg -i test_mpg.mpg
FFmpeg version SVN-r12642, Copyright (c) 2000-2008 Fabrice Bellard, et al.
configuration: --enable-gpl --enable-nonfree --enable-pthreads --enable-shared --enable-liba52 --enable-libamr-nb --enable-libamr-wb --enable-libfaac --enable-libfaad --enable-libmp3lame --enable-libvorbis --enable-libx264
libavutil version: 49.6.0
libavcodec version: 51.54.0
libavformat version: 52.13.0
libavdevice version: 52.0.0
built on Mar 31 2008 16:00:52, gcc: 4.1.2 20070502 (Red Hat 4.1.2-12)
Input #0, mpeg, from 'test_mpg.mpg':
Duration: 00:03:44.8, start: 0.340078, bitrate: 1396 kb/s
Stream #0.0[0x1e0]: Video: mpeg1video, yuv420p, 352x240 [PAR 200:219 DAR 880:657], 1150 kb/s, 29.97 tb(r)
Stream #0.1[0x1c0]: Audio: mp2, 44100 Hz, stereo, 224 kb/s
Must supply at least one output file
PHPで変換前に動画情報を取得しておきたい場合は、これを使えば良さそうです。
こちらに載っていました。有り難うございます。
# コマンドに 2>&1をつけてエラー出力も標準出力へ。
$str_cmd ="ffmpeg -i test_mpg.mpg 2>&1";
# exec関数で標準出力を配列へ取得。
exec($str_cmd,$ary_out);
後は、取得した配列から必要な情報を地道に取り出すだけです。
紆余曲折Tips