読者です 読者をやめる 読者になる 読者になる

ffmpeg で TS をできるだけ高画質な mp4 へ変換してみた

Vine Linux ffmpeg

TS が膨大になる前に、残したいものだけをできるだけ高画質な mp4 にエンコードしてみることにしました。

  • 2012-04-XX 追記:libx264-hq-ts.ffpreset の設定項目の解説を加筆中。とりあえず、level=41 からカキカキしています。
  • 2010-08-XX 追記:なぜかこのページに多数のサイトさまからご紹介いただいているようで恐縮です m(_ _)m せっかくですので、ちょっと説明を加筆中 ... でございます。今ですと、iPad/iPhone 向けに libx264-hq-ts.ffpreset を使えば、ウマー(^o^)/ な感じですヨ。
  • 2009-12-29 追記:プリセットとスクリプトをちょこっと修正。

地上波の映像は、荒い。

まずは、30 秒ほどテストで録画した TS を mplayer で調べてみました。

$ mplayer test.ts
MPlayer 29804-4.1.2 (C) 2000-2009 MPlayer Team
141 audio & 306 video codecs
test.ts を再生中
TS ファイルフォーマットと判断.
VIDEO MPEG2(pid=256) AUDIO AAC(pid=272) NO SUBS (yet)!  PROGRAM N. 1024
VIDEO:  MPEG2  1440x1080  (aspect 3)  29.970 fps  24000.0 kbps (3000.0 kbyte/s)
==========================================================================
映像コーデックを開いています: [mpegpes] MPEG 1/2 Video passthrough
Could not find matching colorspace - retrying with -vf scale...
映像フィルタを開いています: [scale]
選択された映像出力デバイスはコーデックと互換性がありません
映像デコーダの初期化に失敗しました :(
映像コーデックを開いています: [ffmpeg] FFmpeg's libavcodec codec family
Unsupported PixelFormat -1
Selected video codec: [ffmpeg2] vfm: ffmpeg (FFmpeg MPEG-2)
==========================================================================
==========================================================================
音声コーデックを開いています: [faad] AAC (MPEG2/4 Advanced Audio Coding)
FAAD: compressed input bitrate missing, assuming 128kbit/s!
AUDIO: 48000 Hz, 2 ch, s16le, 128.0 kbit/8.33% (ratio: 16000->192000)
Selected audio codec: [faad] afm: faad (FAAD AAC (MPEG-2/MPEG-4 Audio))
==========================================================================
AO: [pulse] 48000Hz 2ch s16le (2 bytes per sample)

地上波の映像は、想像以上に解像度が低いです。つまり、地上波の映像は、粗雑な映像だということです。試しに、ffmpegaspect を 16:9 で保ち、解像度を 1280x720 にしても、気になりませんでした。

TS エンコーディング用の x264 プリセットを作ってみる

ffmpeg に同梱されている libx264-hq.ffpreset がイケています。こいつをベースにして、ffmpeg のヘルプを見ながら、参考文献の先人の皆様の知恵を拝借しつつ、TS 用のプリセットファイル libx264-hq-ts.ffpreset*1 を作ってみました。

level=41
crf=25
coder=1
flags=+loop
cmp=+chroma
partitions=+parti8x8+parti4x4+partp8x8+partb8x8
me_method=umh
subq=7
me_range=16
g=250
keyint_min=25
sc_threshold=40
i_qfactor=0.71
b_strategy=1
qmin=10
rc_eq='blurCplx^(1-qComp)'
bf=16
bidir_refine=1
refs=6
deblockalpha=0
deblockbeta=0

ちなみに、このプリセットには、-crf 25 というシングルパス用の品質基準 VBR を入れているので、マルチパス向けではありません。

拙作 libx264-hq-ts.ffpreset とオリジナル libx264-hq.ffpreset の違い
$ diff -up libx264-hq.ffpreset libx264-hq-ts.ffpreset
--- libx264-hq.ffpreset	2010-07-17 16:16:11.000000000 +0900
+++ libx264-hq-ts.ffpreset	2009-12-29 11:02:08.000000000 +0900
@@ -1,22 +1,21 @@
+level=41
+crf=25
 coder=1
 flags=+loop
 cmp=+chroma
 partitions=+parti8x8+parti4x4+partp8x8+partb8x8
 me_method=umh
-subq=8
+subq=7
 me_range=16
 g=250
 keyint_min=25
 sc_threshold=40
 i_qfactor=0.71
-b_strategy=2
-qcomp=0.6
+b_strategy=1
 qmin=10
-qmax=51
-qdiff=4
-bf=3
-refs=4
-directpred=3
-trellis=1
-flags2=+wpred+mixed_refs+dct8x8+fastpskip
-wpredp=2
+rc_eq='blurCplx^(1-qComp)'
+bf=16
+bidir_refine=1
+refs=6
+deblockalpha=0
+deblockbeta=0
level=41

これは、H.264 のプロファイルのレベルが 4.1 に指定しています。

H.264 のプロファイルとは、簡単にいうと用途別に機能を定義した仕様です。各レベルごとに、おもに解像度とビットレートに影響する、``ある種の制限'' が設けられています。ケータイ電話やスマートフォンiPhoneiPad などの周辺機器が、どのレベルに対応しているかで、再生できたりできなかったりします。

http://ja.wikipedia.org/wiki/H.264 には、H.264 のプロファイルのレベルが一覧表にまとめられています。

とりあえず、極々簡単な TS 変換用スクリプトを書いてみる

簡単な TS 変換用スクリプト ts2mp4.sh を書きます。

#!/bin/bash -x

TS=$1
BASE=$(basename $TS .ts)
[ "${BASE}.ts" = "$(basename $TS)" ] || exit 1

#CPU_CORES=0
CPU_CORES=$(/usr/bin/getconf _NPROCESSORS_ONLN)

X264_HIGH_HDTV="-f mp4 -vcodec libx264 \
    -vpre /some/where/ffmpeg/libx264-hq-ts.ffpreset \
    -r 30000/1001 -aspect 16:9 -s 1280x720 -bufsize 20000k -maxrate 25000k \
    -acodec libfaac -ac 2 -ar 48000 -ab 128k -threads ${CPU_CORES}"

ffmpeg -y -i $TS ${X264_HIGH_HDTV} ${BASE}.mp4

exit

これでエンコードされたファイル容量は割と大きいので、必要であれば、手持ちのハードディスクと自己満足感と相談して、-aspect 16:9 -s 1280x720 を -s 640x480 などに変更すればよいです。

あと、2 pass encoding にも挑戦しましたが、エンコにめっちゃ時間がかかるのと、私の納得のいく画質を保つことが出来なかったので、今回はスルーです。

エンコは奥が深いなとしみじみと感じるひとときを過ごしました。一度でイイから、エンコ職人のプリセットを見てみたい(w

*1:2009/12/27 時点でできたてほやほやです。しばらくしたら、改良している可能大なので、あくまで目安としてくださいませ。例えば、-qmin や -qmax を入れるとか。