主に目的はtsファイルのエンコード。
ワールドカップとってたらあほみたいに領域食い始めたんでなんとかしようと。
全部残す気はないけど一時的に領域くう量が半端なくなってきた。
とりあえず、h.264エンコードするためだけなら、ffmpegがあれば事足りる。
が、ほかにもいくつかのソフトウェアを使う。
とりあえず、構成としては動画部はh.264, 音声部はAACでMP4コンテナに格納する。
AACエンコードには何を使うか悩んだが、ffmpegと一緒にくっついてくるlibfaacは、コードの一部がLGPLに乗っ取っていないとかっていうんで、コンパイルオプションに–enable-nonfree –enable-libfaacとしなくてはならなくなったっていう問題がある。
どういうことかっていうと、faacは非フリーだから配布できません、faacを使いたい場合はnonfreeオプションをつけて自分でコンパイルしてね、nonfreeのものは配布しちゃだめよっていうことだそうだ。
# ffmpeg -formats
FFmpeg version SVN-r23386, Copyright (c) 2000-2010 the FFmpeg developers
built on Jun 3 2010 11:33:42 with gcc 4.4.4
configuration: –enable-libdc1394 –prefix=/usr –extra-cflags=’-Wall -g ‘ –cc=’ccache cc’ –enable-shared –enable-libmp3lame –enable-gpl –enable-libfaad –enable-libvorbis –enable-pthreads –enable-libfaac –enable-libxvid –enable-postproc –enable-x11grab –enable-libgsm –enable-libtheora –enable-libopencore-amrnb –enable-libopencore-amrwb –enable-libx264 –enable-libspeex –enable-nonfree –disable-stripping –enable-avfilter –enable-libdirac –enable-avfilter-lavf –disable-decoder=libdirac –enable-libschroedinger –disable-encoder=libschroedinger –enable-version3 –enable-libopenjpeg –enable-libvpx –disable-altivec –disable-armv5te –disable-armv6 –disable-vis
めっちゃlibfaacとnonfreeオプション有効で配布されてるじゃんwwww@debian/sid
まあ、それはともかく、そういうわけでいつ使えなくなってもおかしくないっていうかたぶんディストリビューションによってはすでに無効化されて配布されているものもあるだろうし、AAC-LCにしか対応していないっていうのもあるし、neroはHE-AACに対応してるんで、Nero AAC Codecを使ってAACエンコードをしようと思う。
作業の流れとしては以下のようになる。
- .tsファイルを動画部と音声部(wav)に分離
- 動画部をffmpegでh.264形式に
- 音声部をnero aac codecでHE-AACに
- MP4Boxで合体
と思ったんだけど、よくよく考えてみれば、tsの音声って元々AACなわけで、それをwavにしてまたAACにするのはばかげてる。
ということで、単純に音声はそのまま使い回せばいいじゃないかという結論に。
とりあえずffmpegの使い方を調べる。
- -formats 対応フォーマットの表示。D=デコード可能 E=エンコード可能
- -codecs 対応コーデック。D=デコード可能 E=エンコード可能。
V/A/S Video Audio Subtitle
S=スライス対応 D=ダイレクトレンダリング T=フレーム境界以外の入力対応
- -bsfs ビットストリームフィルタ
- -protocols プロトコル
- -filters libavfilterで利用可能なフィルタ
- -pix_fmt ピクセルフォーマット
- -i filename 入力ファイル
- -y 出力ファイルを上書きする
- -fs limit_size ファイルサイズの上限
- -b bitrate ビットレート デフォルト 200kb/s
- -r fps フレームレート デフォルト25
- -s size サイズ。デフォルトソースと同じ。128×96とかqvgaとかで指定。
- -aspect aspect アスペクトレートを指定(4:3, 16:9)
- -vn 映像のレコードを行わない
- -vcodec codec ビデオコーデックを指定のものに強制
- -sameq ソースと同じ映像品質を保つ
- -pass 1 or 2 2パスエンコードに使う。1パス目はオーディオを/dev/nullに流し込む
ffmpeg -i foo.mov -vcodec libxvid -pass 1 -an -f rawvideo -y /dev/null
- -ar freq オーディオサンプリング周波数の指定。デフォルト44.1KHz
- -ab bitrate オーディオビットレートの指定。デフォルト64k
- -aq q オーディオ品質の指定 コーデックによるVBR
- -ac channels オーディオチャンネル数の指定。デフォルト1チャンネル
- -an オーディオレコーディングを行わない
- -acodec codec オーディオコーデックの指定
使う可能性がありそうなものだけ適当に翻訳。
ということでエンコードしてみようとした。
$ ffmpeg -i “2010FIFAワールドカップ 日本VSオランダ.ts” -f mp4 -vcodec libx264 -r 30000/1001 -b 8192k -acodec copy -y test.mp4
FFmpeg version SVN-r23386, Copyright (c) 2000-2010 the FFmpeg developers
built on Jun 3 2010 11:33:42 with gcc 4.4.4
configuration: –enable-libdc1394 –prefix=/usr –extra-cflags=’-Wall -g ‘ –cc=’ccache cc’ –enable-shared –enable-libmp3lame –enable-gpl –enable-libfaad –enable-libvorbis –enable-pthreads –enable-libfaac –enable-libxvid –enable-postproc –enable-x11grab –enable-libgsm –enable-libtheora –enable-libopencore-amrnb –enable-libopencore-amrwb –enable-libx264 –enable-libspeex –enable-nonfree –disable-stripping –enable-avfilter –enable-libdirac –enable-avfilter-lavf –disable-decoder=libdirac –enable-libschroedinger –disable-encoder=libschroedinger –enable-version3 –enable-libopenjpeg –enable-libvpx –disable-altivec –disable-armv5te –disable-armv6 –disable-vis
libavutil 50.16. 0 / 50.16. 0
libavcodec 52.73. 0 / 52.73. 0
libavformat 52.67. 0 / 52.67. 0
libavdevice 52. 2. 0 / 52. 2. 0
libavfilter 1.20. 0 / 1.20. 0
libswscale 0.11. 0 / 0.11. 0
libpostproc 51. 2. 0 / 51. 2. 0
[aac @ 0x654c30]Not evaluating a further program_config_element as this construct is dubious at best.
[aac @ 0x699420]channel element 2.14 is not allocated
[mpeg2video @ 0x654400]mpeg_decode_postinit() failure
Last message repeated 9 times
[NULL @ 0x698c30]non-existing PPS referenced
[h264 @ 0x698c30]non-existing PPS 0 referenced
[h264 @ 0x698c30]decode_slice_header error
[h264 @ 0x698c30]no frame!
[h264 @ 0x698c30]non-existing PPS referenced
[h264 @ 0x698c30]non-existing PPS 0 referenced
[h264 @ 0x698c30]decode_slice_header error
[h264 @ 0x698c30]no frame!
[h264 @ 0x698c30]non-existing PPS referenced
[h264 @ 0x698c30]non-existing PPS 0 referenced
[h264 @ 0x698c30]decode_slice_header error
[h264 @ 0x698c30]no frame!
[h264 @ 0x698c30]non-existing PPS referenced
[h264 @ 0x698c30]non-existing PPS 0 referenced
[h264 @ 0x698c30]decode_slice_header error
[h264 @ 0x698c30]no frame!
[mpeg2video @ 0x654400]mpeg_decode_postinit() failure
Last message repeated 3 times
[h264 @ 0x698c30]non-existing PPS referenced
[h264 @ 0x698c30]non-existing PPS 0 referenced
[h264 @ 0x698c30]decode_slice_header error
[h264 @ 0x698c30]no frame!
[h264 @ 0x698c30]non-existing PPS referenced
[h264 @ 0x698c30]non-existing PPS 0 referenced
[h264 @ 0x698c30]decode_slice_header error
[h264 @ 0x698c30]no frame!
[h264 @ 0x698c30]non-existing PPS referenced
[h264 @ 0x698c30]non-existing PPS 0 referenced
[h264 @ 0x698c30]decode_slice_header error
[h264 @ 0x698c30]no frame!
[h264 @ 0x698c30]non-existing PPS referenced
[h264 @ 0x698c30]non-existing PPS 0 referenced
[h264 @ 0x698c30]decode_slice_header error
[h264 @ 0x698c30]no frame!
[h264 @ 0x698c30]non-existing PPS referenced
[h264 @ 0x698c30]non-existing PPS 0 referenced
[h264 @ 0x698c30]decode_slice_header error
[h264 @ 0x698c30]no frame!
[h264 @ 0x698c30]non-existing PPS referenced
[h264 @ 0x698c30]non-existing PPS 0 referenced
[h264 @ 0x698c30]decode_slice_header error
[h264 @ 0x698c30]no frame!
[h264 @ 0x698c30]non-existing PPS referenced
[h264 @ 0x698c30]non-existing PPS 0 referenced
[h264 @ 0x698c30]decode_slice_header error
[h264 @ 0x698c30]no frame!
[h264 @ 0x698c30]non-existing PPS referenced
[h264 @ 0x698c30]non-existing PPS 0 referenced
[h264 @ 0x698c30]decode_slice_header error
[h264 @ 0x698c30]no frame!
[h264 @ 0x698c30]non-existing PPS referenced
[h264 @ 0x698c30]non-existing PPS 0 referenced
[h264 @ 0x698c30]decode_slice_header error
[h264 @ 0x698c30]no frame!
[h264 @ 0x698c30]non-existing PPS referenced
[h264 @ 0x698c30]non-existing PPS 0 referenced
[h264 @ 0x698c30]decode_slice_header error
[h264 @ 0x698c30]no frame!
[h264 @ 0x698c30]non-existing PPS referenced
[h264 @ 0x698c30]non-existing PPS 0 referenced
[h264 @ 0x698c30]decode_slice_header error
[h264 @ 0x698c30]no frame!
[h264 @ 0x698c30]non-existing PPS referenced
[h264 @ 0x698c30]non-existing PPS 0 referenced
[h264 @ 0x698c30]decode_slice_header error
[h264 @ 0x698c30]no frame!
[h264 @ 0x698c30]non-existing PPS referenced
[h264 @ 0x698c30]non-existing PPS 0 referenced
[h264 @ 0x698c30]decode_slice_header error
[h264 @ 0x698c30]no frame!
[h264 @ 0x698c30]non-existing PPS referenced
[h264 @ 0x698c30]non-existing PPS 0 referenced
[h264 @ 0x698c30]decode_slice_header error
[h264 @ 0x698c30]no frame!
[h264 @ 0x698c30]non-existing PPS referenced
[h264 @ 0x698c30]non-existing PPS 0 referenced
[h264 @ 0x698c30]decode_slice_header error
[h264 @ 0x698c30]no frame!
[h264 @ 0x698c30]non-existing PPS referenced
[h264 @ 0x698c30]non-existing PPS 0 referenced
[h264 @ 0x698c30]decode_slice_header error
[h264 @ 0x698c30]no frame!
[h264 @ 0x698c30]non-existing PPS referenced
[h264 @ 0x698c30]non-existing PPS 0 referenced
[h264 @ 0x698c30]decode_slice_header error
[h264 @ 0x698c30]no frame!
[h264 @ 0x698c30]non-existing PPS referenced
[h264 @ 0x698c30]non-existing PPS 0 referenced
[h264 @ 0x698c30]decode_slice_header error
[h264 @ 0x698c30]no frame!
[h264 @ 0x698c30]non-existing PPS referenced
[h264 @ 0x698c30]non-existing PPS 0 referenced
[h264 @ 0x698c30]decode_slice_header error
[h264 @ 0x698c30]no frame!
[h264 @ 0x698c30]non-existing PPS referenced
[h264 @ 0x698c30]non-existing PPS 0 referenced
[h264 @ 0x698c30]decode_slice_header error
[h264 @ 0x698c30]no frame!
[h264 @ 0x698c30]non-existing PPS referenced
[h264 @ 0x698c30]non-existing PPS 0 referenced
[h264 @ 0x698c30]decode_slice_header error
[h264 @ 0x698c30]no frame!
[NULL @ 0x66df00]start time is not set in av_estimate_timings_from_pts
[NULL @ 0x66e6f0]start time is not set in av_estimate_timings_from_pts
[NULL @ 0x66eee0]start time is not set in av_estimate_timings_from_pts
[NULL @ 0x66f6d0]start time is not set in av_estimate_timings_from_pts
[NULL @ 0x66fec0]start time is not set in av_estimate_timings_from_pts
[NULL @ 0x6706b0]start time is not set in av_estimate_timings_from_pts
[NULL @ 0x670ea0]start time is not set in av_estimate_timings_from_pts
[NULL @ 0x671690]start time is not set in av_estimate_timings_from_pts
[NULL @ 0x699c50]start time is not set in av_estimate_timings_from_pts
[NULL @ 0x69a480]start time is not set in av_estimate_timings_from_pts
[NULL @ 0x69acb0]start time is not set in av_estimate_timings_from_pts
[NULL @ 0x69b4e0]start time is not set in av_estimate_timings_from_pts
[NULL @ 0x69bd10]start time is not set in av_estimate_timings_from_pts
Input #0, mpegts, from ‘2010FIFAワールドカップ 日本VSオランダ.ts':
Duration: 02:29:31.14, start: 60000.803067, bitrate: 14572 kb/s
Program 1064 ニ・D+F|
Metadata:
name : ニ・D+F|
provider_name :
Stream #0.0[0x111]: Video: mpeg2video, yuv420p, 1440×1080 [PAR 4:3 DAR 16:9], 20000 kb/s, 34.90 fps, 29.97 tbr, 90k tbn, 59.94 tbc
Stream #0.1[0x112]: Audio: aac, 48000 Hz, 5.1, s16, 381 kb/s
Stream #0.2[0x114]: Data: [6][0][0][0] / 0x0006
Stream #0.3[0x115]: Data: [6][0][0][0] / 0x0006
Stream #0.4[0x1000]: Data: [13][0][0][0] / 0x000D
Stream #0.5[0x1001]: Data: [13][0][0][0] / 0x000D
Stream #0.6[0x1002]: Data: [13][0][0][0] / 0x000D
Stream #0.7[0x1003]: Data: [13][0][0][0] / 0x000D
Stream #0.8[0x1004]: Data: [13][0][0][0] / 0x000D
Stream #0.9[0x1005]: Data: [13][0][0][0] / 0x000D
Stream #0.10[0x1006]: Data: [13][0][0][0] / 0x000D
Program 1065 ニ・D+F|
Metadata:
name : ニ・D+F|
provider_name :
Stream #0.0[0x111]: Video: mpeg2video, yuv420p, 1440×1080 [PAR 4:3 DAR 16:9], 20000 kb/s, 34.90 fps, 29.97 tbr, 90k tbn, 59.94 tbc
Stream #0.1[0x112]: Audio: aac, 48000 Hz, 5.1, s16, 381 kb/s
Stream #0.2[0x114]: Data: [6][0][0][0] / 0x0006
Stream #0.3[0x115]: Data: [6][0][0][0] / 0x0006
Stream #0.4[0x1000]: Data: [13][0][0][0] / 0x000D
Stream #0.5[0x1001]: Data: [13][0][0][0] / 0x000D
Stream #0.6[0x1002]: Data: [13][0][0][0] / 0x000D
Stream #0.7[0x1003]: Data: [13][0][0][0] / 0x000D
Stream #0.8[0x1004]: Data: [13][0][0][0] / 0x000D
Stream #0.9[0x1005]: Data: [13][0][0][0] / 0x000D
Stream #0.10[0x1006]: Data: [13][0][0][0] / 0x000D
Program 1066 ニ・D+F|
Metadata:
name : ニ・D+F|
provider_name :
Stream #0.0[0x111]: Video: mpeg2video, yuv420p, 1440×1080 [PAR 4:3 DAR 16:9], 20000 kb/s, 34.90 fps, 29.97 tbr, 90k tbn, 59.94 tbc
Stream #0.1[0x112]: Audio: aac, 48000 Hz, 5.1, s16, 381 kb/s
Stream #0.2[0x114]: Data: [6][0][0][0] / 0x0006
Stream #0.3[0x115]: Data: [6][0][0][0] / 0x0006
Stream #0.4[0x1000]: Data: [13][0][0][0] / 0x000D
Stream #0.5[0x1001]: Data: [13][0][0][0] / 0x000D
Stream #0.6[0x1002]: Data: [13][0][0][0] / 0x000D
Stream #0.7[0x1003]: Data: [13][0][0][0] / 0x000D
Stream #0.8[0x1004]: Data: [13][0][0][0] / 0x000D
Stream #0.9[0x1005]: Data: [13][0][0][0] / 0x000D
Stream #0.10[0x1006]: Data: [13][0][0][0] / 0x000D
Program 1448 ニ・D+F|
Metadata:
name : ニ・D+F|
provider_name :
Stream #0.11[0x181]: Video: h264, yuv420p, 320×180, 42.65 fps, 14.99 tbr, 90k tbn, 29.97 tbc
Stream #0.12[0x182]: Audio: aac, 48000 Hz, stereo, s16, 45 kb/s
Stream #0.13[0x184]: Data: [6][0][0][0] / 0x0006
Stream #0.14[0x1030]: Data: [13][0][0][0] / 0x000D
Stream #0.15[0x103b]: Data: [13][0][0][0] / 0x000D
Stream #0.16[0x1039]: Data: [13][0][0][0] / 0x000D
Stream #0.17[0x103a]: Data: [13][0][0][0] / 0x000D
[scale @ 0x6517d0]w:1440 h:1080 fmt:yuv420p -> w:320 h:180 fmt:yuv420p flags:0xa0000004
[libx264 @ 0x69c160]broken ffmpeg default settings detected
[libx264 @ 0x69c160]use an encoding preset (vpre)
Output #0, mp4, to ‘test.mp4′:
Stream #0.0: Video: libx264, yuv420p, 320×180, q=2-31, 8192 kb/s, 90k tbn, 29.97 tbc
Stream #0.1: Audio: libfaac, 48000 Hz, 5.1, 381 kb/s
Stream mapping:
Stream #0.0 -> #0.0
Stream #0.1 -> #0.1
Error while opening encoder for output stream #0.0 – maybe incorrect parameters such as bit_rate, rate, width or height
とりあえずなんかエラーがでたのだけはわかった。
んーと。とりあえずたぶん一番問題なのは赤字の部分な気がする。
ということで調べてみる。
プリセットファイル
ffpresetsディレクトリ調べてミロや。
プリセットファイルは vpre, apre, spre, fpreオプションがある。
fpreはコーデックの種別に応じたファイル名に関するもの。
vpre, apre, spreはプリセットオプションの同じタイプの選択されたコーデックに適用される。
vpre, apre, spreに渡された値は、引数.ffpresetファイルを以下のディレクトリ順に検索を行う。
- $FFMPEG_DATADIR
- $HOME/.ffmpeg
- PREFIX/share/ffmpeg
libx264-maxだったらlibx264-max.ffpresetファイルを上記のディレクトリから探しに行く。
その名前で見つからなかったら、codec_name-arg.ffpresetで探しに行く。
-vcodec libx264 -vpre maxなら、libx264-max.ffpresetとなる。
っていうことで、まあとりあえず、libx264でエンコードするときはvpreでプリセットを指定しやがれこの野郎っていうことでいいんだろうか。
プリセットってそもそも何かいてんだろうか。
みてみよう。
/usr/share/ffmpegを眺めてみたらこんな感じ。
libx264-baseline.ffpreset libx264-medium.ffpreset
libx264-default.ffpreset libx264-medium_firstpass.ffpreset
libx264-fast.ffpreset libx264-normal.ffpreset
libx264-fast_firstpass.ffpreset libx264-placebo.ffpreset
libx264-faster.ffpreset libx264-placebo_firstpass.ffpreset
libx264-faster_firstpass.ffpreset libx264-slow.ffpreset
libx264-fastfirstpass.ffpreset libx264-slow_firstpass.ffpreset
libx264-hq.ffpreset libx264-slower.ffpreset
libx264-ipod320.ffpreset libx264-slower_firstpass.ffpreset
libx264-ipod640.ffpreset libx264-slowfirstpass.ffpreset
libx264-lossless_fast.ffpreset libx264-superfast.ffpreset
libx264-lossless_max.ffpreset libx264-superfast_firstpass.ffpreset
libx264-lossless_medium.ffpreset libx264-ultrafast.ffpreset
libx264-lossless_slow.ffpreset libx264-ultrafast_firstpass.ffpreset
libx264-lossless_slower.ffpreset libx264-veryfast.ffpreset
libx264-lossless_ultrafast.ffpreset libx264-veryfast_firstpass.ffpreset
libx264-main.ffpreset libx264-veryslow.ffpreset
libx264-max.ffpreset libx264-veryslow_firstpass.ffpreset
めっちゃlibx264用のプリセットだらけ。
libx264-default.ffpreset
をとりあえずみてみる。
coder=1
flags=+loop
cmp=+chroma
partitions=+parti8x8+parti4x4+partp8x8+partb8x8
me_method=hex
subq=7
me_range=16
g=250
keyint_min=25
sc_threshold=40
i_qfactor=0.71
b_strategy=1
qcomp=0.6
qmin=10
qmax=51
qdiff=4
bf=3
refs=3
directpred=1
trellis=1
flags2=+mixed_refs+wpred+dct8x8+fastpskip
wpredp=2
んー。
とってもman ffmpegやってもヒットしないオプション多数。
ということで探したらみつかった。
FFmpeg option |
x264 option |
-g <frames> |
–keyint |
-b <bits per second> |
–bitrate |
-bufsize <bits> |
–vbv-bufsize |
-maxrate <bits> |
–vbv-maxrate |
-pass <1,2,3> |
–pass |
-crf <float> |
–crf |
-cqp <int> |
–qp |
-bf <int> |
–bframes |
-coder <0,1> |
–no-cabac/nothing |
-b_strategy <0,1> |
–no-b-adapt/nothing |
-bframebias <int> |
–b-bias |
-keyint_min <int> |
–min-keyint |
-sc_threshold <int> |
–scenecut |
-deblockalpha <int>
-deblockbeta <int>
|
–deblock |
-qmin <int> |
–qpmin |
-qmax <int> |
–qpmax |
-qdiff <int> |
–qpstep |
-qcomp <float> |
–qcomp |
-qblur <float> |
–qblur |
-complexityblur <float> |
–cplxblur |
-refs <int> |
–ref |
-directpred <int> |
–direct |
-me_method <dia,hex,umh,tesa> |
–me |
-me_range <int> |
–merange |
-subq <int> |
–subme |
-trellis <0,1,2> |
–trellis |
-nr <int> |
–nr |
-level <int> |
–level |
-bt <bits> |
–ratetol = -bt / -b |
-rc_init_occupancy <bits> |
–vbv-init = -rc_init_occupancy / -bufsize |
-i_qfactor <float> |
–ipratio = 1 / -i_qfactor |
-b_qfactor <float> |
–pbratio |
-chromaoffset <int> |
–chroma-qp-offset |
-rc_eq <string> |
–rc_eq |
-threads <int> |
–threads |
-cmp <-chroma/+chroma> |
–no-chroma-me/nothing |
-partitions |
–partitions |
+parti8x8 |
i8x8 |
+parti4x4 |
i4x4 |
+partp8x8 |
p8x8 |
+partp4x4 |
p4x4 |
+partb8x8 |
b8x8 |
-flags |
|
-loop/+loop |
–no-deblock/–deblock |
-psnr/+psnr |
–no-psnr/nothing |
-flags2 |
|
+bpyramid |
–b-pyramid |
+wpred |
–weightb |
+mixed_refs |
–mixed-refs |
+dct8x8 |
–8x8dct |
-fastpskip/+fastpskip |
–no-fast-pskip/nothing |
+aud |
–aud |
ということでこのプリセットはlibx264に渡すパラメータらしい。
とりあえず、ffmpegを使ったh.264エンコードにはここがとても参考になる。
基本を簡単に押さえておくと、以下のような感じらしい。
- CQP(constant quantization parameter 固定量子化パラメータ)はやりたいことがわかってる人以外おすすめできない
ついでにCQPの意味がさっぱりわからない。
とりあえず大きくするとビットレートが下がるのは確か。
- 圧縮率よりも質だっていう1パスエンコードでいきたい人にはCRF(constant rate factor 固定レート要素)がおすすめ
質重視なら25-15の値を使うといいらしい。
値が低いほど高画質で高ビットレート。
- ストリーミング用途だとかビットレートを重要視するけど2パスはめんどいってひとは1パスで平均ビットレート(ABR)がおすすめ
- ビットレートを重要視して2パスエンコードする時間がある人は、2パスエンコードの可変ビットレート(VBR)がおすすめ
CQPはとりあえずCRFに取って代わられる存在だそうだ。
ちなみにここでビットレートを重要視する、っていうのは、低く抑えたいっていうことが念頭にある。
2パスVBRの例
ffmpeg -i INPUT -an -pass 1 -vcodec libx264 -vpre slow_firstpass -b BIT_RATE -bt BIT_RATE -threads 0 OUTPUT.mp4
ffmpeg -i INPUT -acodec libfaac -ab 128k -pass 2 -vcodec libx264 -vpre slow -b BIT_RATE -bt BIT_RATE -threads 0 OUTPUT.mp4
1パスABRの例
ffmpeg -i INPUT -acodec libfaac -ab 128k -vcodec libx264 -vpre slow -b BIT_RATE -bt BIT_RATE -threads 0 OUTPUT.mp4
1パスCRFの例
ffmpeg -i INFILE -acodec libfaac -ab 96k -vcodec libx264 -vpre slow -crf 22 -threads 0 OUTPUT.mp4
さて、これらを踏まえると、やりたい形は以下のような感じだろうか。
ffmpeg -i INFILE -acodec copy -vcodec libx264 -vpre slow -crf 22 -thread 0 OUTPUT.mp4
んだが、tsファイルの情報をよく見ると変なところがある。
Stream #0.11[0x181]: Video: h264, yuv420p, 320×180, 42.65 fps, 14.99 tbr, 90k tbn, 29.97 tbc
Stream #0.12[0x182]: Audio: aac, 48000 Hz, stereo, s16, 45 kb/s
Stream #0.11と#0.12に映像と音声が。
h264の映像とAACの音声があるって。
これワンセグのデータか。
いろいろといじくってみてわかったところとしては、tsに含まれているAACをそのまま使おうとしても再生できない。
たぶんメタデータが関係しているんだろう。
いったん音声と映像を分離しておいて、MP4Boxでコンテナに配置してやればちゃんと再生されることがわかった。
そのあともいろいろいじくってみたところ、最終的な流れは以下のようにすることになった。
- tsからフルセグデータを分離
- AACデータを分離
- 映像をh264エンコード 音声は出力しない
- MP4Boxで結合
必要なパッケージdebian multimediaをapt sourceに記述して以下を持ってくる。
ということで、まずフルセグデータだけ抜く。
フルセグデータが含まれているProgram IDをtsinfoで取得して指定している。
$ ffmpeg -i source.ts -programid `tsinfo source.ts | grep “Program [0-9]+,” | sed s/” Program “// | sed s/,.*//` -vcodec copy -acodec copy source.fullseg.ts
次に、AACだけを抽出する。
$ ffmpeg -i source.fullseg.ts -vn -acodec copy source.aac
次に、映像をh264エンコード。
$ ffmpeg -i source.fullseg.ts -f h264 -vcodec libx264 -vpre slow -r 30000/1001 -crf 20 -an source.264
最後にMP4Boxで結合
$ MP4Box -mpeg4 -fps 29.970030 -add source.264 -add source.aac -new source.mp4
っていう感じでいけた。
ということでシェルスクリプトを書く。
かきながら、フルセグデータだけの切り取りステップは不要なことに気づいたので、その点直した。
#/bin/sh
# get Program ID
ID=`tsinfo "$1" | grep "Program [0-9]+," | sed s/"Program"// | sed s/,.*// | sed s/" "//`
# seperate aac
ffmpeg -i "$1" -programid $ID -vn -y -acodec copy /tmp/fullseg.aac
# encode video
ffmpeg -i "$1" -programid $ID -f h264 -an -y -vcodec libx264 -vpre slow -crf 22 -r 30000/1001 /tmp/fullseg.264
# merge video and audio
MP4Box -mpeg4 -fps 29.970030 -add /tmp/fullseg.264 -add /tmp/fullseg.aac -new "$1.mp4"
# remove tmp files
rm -f /tmp/fullseg.*
ここまでたどり着くのに三日かかったじぇ。。。