これに限らず、不定な解像度・縦横比の動画を、適切にレターボックス化またはサイドパネル化するのは結構難しく、以下のようなコマンドが必要になる。
ffmpeg -i "input.mp4" -vf "yadif=deint=interlaced, scale=w=trunc(ih*dar/2)*2:h=trunc(ih/2)*2, setsar=1/1, scale=w=1920:h=1080:force_original_aspect_ratio=1, pad=w=1920:h=1080:x=(ow-iw)/2:y=(oh-ih)/2:color=#000000" -pix_fmt yuv420p "output.mp4"
このコマンドを使うことで、入力動画のサイズを気にすることなく指定のサイズにして出力できる。出力サイズ(解像度)はw=1920:h=1080となっているところ(2箇所)で指定する。
color=#000000 となっているところで別のカラーコードを指定すれば、上下左右に付ける帯の色を黒以外にすることができる。
海外の質問サイトにあった回答を元にしているけれど、この回答にあるコマンドでは正方ピクセルの動画しか対応できないので、フィルタ処理の前段に scale=w=trunc(ih*dar/2)*2:h=trunc(ih/2)*2, setsar=1/1 を入れて、正方ピクセルでない動画も正方ピクセルに直している。(基本的なことだが、ffmpegのフィルタは書いた順に実行される。)scaleで/2とか*2しているのは、サイズを偶数にしないと一部の出力形式にするときにエラーが出るため。
この追加の処理により、解像度が720x480固定でありながら表示は16:9や4:3になるDVDの映像(VOBファイル)などにも対応することができる。
また、フィルタの最初にある yadif=deint=interlaced はインタレース解除フィルタ。出力はプログレッシブになるので、たとえ入力動画がインタレースでも対応できるようにしている。deint=interlaced を付けることで、インタレースだとマークされている部分だけをインタレース解除するように働いてくれるので、プログレッシブな入力動画も同一コマンドで処理できる。(プログレッシブな動画にyadifフィルタが適用されてしまうと、輪郭に縞模様が出ることがある。)しかし、これは万能ではなく、元動画を作成したエンコーダによっては、たとえインタレース動画でもインタレースの部分にマークを付けないことがあり、この場合はインタレースが解除されない。確実にインタレースが解除されるようにするには、ffprobeとかffmpegのidetフィルタとかで入力動画がインタレースであるか調べて、適切にyadifフィルタを適用するようにバッチなりプログラムなりを組む必要がある。Windowsのバッチファイルなら、この記事に書いたような方法で条件分岐することになる。
出力をインタレースの動画にする場合、入力がプログレッシブだったら単に -flags +ilme+ildct オプションを付ければ良いが、入力がインタレースだった場合はインタレ保持するようにコマンドを考えないといけない。困ったことにffmpegは昔から(2018年現在最新のver4.0でも)動画の高さ(height)が変わるとインタレースを保持できない、という問題を抱えている。なので、一旦yadifフィルタの片フィールド補完を使って「インタレース → fpsが2倍のプログレッシブ」に変換し、サイズを変更した後、tinterlaceフィルタで「fpsが2倍のプログレッシブ → 元のfpsのインタレース」に戻す。そのコマンドは以下のようになる。(以下のコマンドはインタレースの入力動画専用なので注意!)
ffmpeg -i "input.mp4" -vf "yadif=mode=send_field, scale=w=trunc(ih*dar/2)*2:h=trunc(ih/2)*2, setsar=1/1, scale=w=1920:h=1080:force_original_aspect_ratio=1, pad=w=1920:h=1080:x=(ow-iw)/2:y=(oh-ih)/2:color=#000000, tinterlace=4" -pix_fmt yuv420p -flags +ilme+ildct "output.mp4"
タグ:FFmpeg
ffplay -i "input.mp4" -vf "yadif=deint=interlaced,scale=trunc(oh*dar/2)*2:1080, setsar=1/1,pad=ih*16/9:ih:(ow-iw)/2:0:color=#000000"
失礼しました。