携帯へ動画を入れる

現行の端末で表示できる動画はほとんどがMPEG-43GPPのコンテナに入れたもの。AVC以前のMPEG-4と言っても様々なオプション仕様があるためどれを使った状態の動画を喰うかは端末依存。端末のメーカも詳細な情報を積極的に出しているわけじゃないので、どこまで使えるかは試行錯誤して試すしかない。幸いユーザがまとめているWikiがあるので、ここらを参考にしつつパラメータを決める。とりあえず圧縮度に寄与しそうなパラメータを有効にしまくっていたら、再生時のエラーが出るのでどこが間違っているのかと思っていたが、ようはそういうことらしい。
最近のffmpegでは個別の拡張機能をどこまで使うかを列挙していける。具体的には以下のフラグの一覧。

-flags             <flags> EDVA.
   mv4                     E.V.. use four motion vector by macroblock (mpeg4)
   obmc                    E.V.. use overlapped block motion compensation (h263+)
   qpel                    E.V.. use 1/4 pel motion compensation
   loop                    E.V.. use loop filter
   gmc                     E.V.. use gmc
   mv0                     E.V.. always try a mb with mv=<0,0>
   part                    E.V.. use data partitioning
   gray                    EDV.. only decode/encode grayscale
   psnr                    E.V.. error[?] variables will be set during encoding
   naq                     E.V.. normalize adaptive quantization
   ildct                   E.V.. use interlaced dct
   low_delay               EDV.. force low delay
   alt                     E.V.. enable alternate scantable (mpeg2/mpeg4)
   trell                   E.V.. use trellis quantization
   bitexact                EDVAS use only bitexact stuff (except (i)dct)
   aic                     E.V.. h263 advanced intra coding / mpeg4 ac prediction
   umv                     E.V.. use unlimited motion vectors
   cbp                     E.V.. use rate distortion optimization for cbp
   qprd                    E.V.. use rate distortion optimization for qp selection
   aiv                     E.V.. h263 alternative inter vlc
   slice                   E.V..
   ilme                    E.V.. interlaced motion estimation
   scan_offset             E.V.. will reserve space for svcd scan offset user data
   cgop                    E.V.. closed gop

私の今使っている端末では" -flags +mv4+trell+bitexact+aic "ってな感じになる。これ以外も使えるものがあるのかもしれないが、全ての組合せでエンコードして試すのは大変なのでまぁこんなところで。
オーディオはAACかAMR_NB。後者は通話のコーデックでも使われるぐらいで周波数が8kHzで固定。映像と合わせて見るとちょっとしょぼい。通常はAACを使う。
エラー処理とかが適当だけど2passでエンコードするときは以下のような感じ。

#!/bin/sh
FILE=$1
TITLE=$2
OUTDIR="/export/"
TEMP=pass.$$
AUDIO_PARAM="-acodec libfaac -ac 2 -ar 22050 -ab 64k -vol 256"
#AUDIO_PARAM="-acodec libmp3lame -ac 2 -ar 22050 -ab 96k -vol 256"
#AUDIO_PARAM="-ar 16000 -ac 1 -acodec libamr_wb -ab 23.85k"
#AUDIO_PARAM="-ar 8000 -ac 1 -acodec libamr_nb -ab 12.2k"
VIDEO_PARAM="-aspect 4:3  -vcodec libxvid -flags +mv4+trell+bitexact+aic -me_method full -g 240
  -mbd rd  -s 320x240 -nr 500 -b 240k"

/usr/bin/ffmpeg -y -re -i $FILE -an $VIDEO_PARAM -f 3gp -pass 1 -passlogfile $TEMP /dev/null
if [ $? != "0" ] ; then
        rm $TEMP-0.log
        exit 1
fi

/usr/bin/ffmpeg -y -re -i $FILE $AUDIO_PARAM $VIDEO_PARAM -f 3gp -pass 2 -passlogfile $TEMP "$O
UTDIR$TITLE.3gp"

rm $TEMP-0.log

エントリモデルの携帯でも案外実用になるレベルの動画再生能力がある。最終的にMicroSDに書き込むときのファイル名が決め打ちだったりするのが微妙にダサいが、これだけの能力がありながらあまり一般ユーザには浸透していないのはもったいないなぁ。下手にiPodとかで見るより便利だと思うのだけど。