FFmpeg で動画変換

動画変換環境を Windows -> Linux へ移行しようと考えています。

Linux 環境のエンコード環境を考える – あららぼ

まず、著名な FFmpeg を使ってみることにしました。

導入

Download FFmpeg

Builds - CODEX FFMPEG @ gyan.dev
latest git master branch build version: 2024-12-26-git-fe04b93afa
ffmpeg-git-full.7z

  • インストール
$ cat /etc/issue
Ubuntu 24.04.1 LTS \n \l

$ sudo apt update -y && sudo apt install -y ffmpeg
  • バージョン
$ ffmpeg -version
ffmpeg version 6.1.1-3ubuntu5 Copyright (c) 2000-2023 the FFmpeg developers
built with gcc 13 (Ubuntu 13.2.0-23ubuntu3)
configuration: --prefix=/usr --extra-version=3ubuntu5 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --disable-omx --enable-gnutls --enable-libaom --enable-libass --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libdav1d --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libglslang --enable-libgme --enable-libgsm --enable-libharfbuzz --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzimg --enable-openal --enable-opencl --enable-opengl --disable-sndio --enable-libvpl --disable-libmfx --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-ladspa --enable-libbluray --enable-libjack --enable-libpulse --enable-librabbitmq --enable-librist --enable-libsrt --enable-libssh --enable-libsvtav1 --enable-libx264 --enable-libzmq --enable-libzvbi --enable-lv2 --enable-sdl2 --enable-libplacebo --enable-librav1e --enable-pocketsphinx --enable-librsvg --enable-libjxl --enable-shared
libavutil      58. 29.100 / 58. 29.100
libavcodec     60. 31.102 / 60. 31.102
libavformat    60. 16.100 / 60. 16.100
libavdevice    60.  3.100 / 60.  3.100
libavfilter     9. 12.100 /  9. 12.100
libswscale      7.  5.100 /  7.  5.100
libswresample   4. 12.100 /  4. 12.100
libpostproc    57.  3.100 / 57.  3.100

使い方

既存動画の情報取得

コーデックや解像度、ビットレートが確認できます。

$ ffmpeg -i yyy.mp4
ffmpeg version 6.1.1-3ubuntu5 Copyright (c) 2000-2023 the FFmpeg developers
  built with gcc 13 (Ubuntu 13.2.0-23ubuntu3)
  configuration: ... right description omitted ...
  libavutil      58. 29.100 / 58. 29.100
  libavcodec     60. 31.102 / 60. 31.102
  libavformat    60. 16.100 / 60. 16.100
  libavdevice    60.  3.100 / 60.  3.100
  libavfilter     9. 12.100 /  9. 12.100
  libswscale      7.  5.100 /  7.  5.100
  libswresample   4. 12.100 /  4. 12.100
  libpostproc    57.  3.100 / 57.  3.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'yyy.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomdby1iso2avc1mp41
    encoder         : Lavf60.16.100
  Duration: 00:15:36.57, start: 0.000000, bitrate: 9062 kb/s
  Stream #0:0[0x1](und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(progressive), 1920x1080 [SAR 1:1 DAR 16:9], 8608 kb/s, 29.97 fps, 29.97 tbr, 30k tbn (default)
    Metadata:
      handler_name    : VideoHandler
      vendor_id       : [0][0][0][0]
      encoder         : Lavc60.31.102 libx264
  Stream #0:1[0x2](und): Audio: ac3 (ac-3 / 0x332D6361), 48000 Hz, stereo, fltp, 448 kb/s (default)
    Metadata:
      handler_name    : SoundHandler
      vendor_id       : [0][0][0][0]
    Side data:
      audio service type: main
At least one output file must be specified

動画形式の変換

  • 構文
    $ ffmpeg -i {input} {option} {output}

形式変更( ex. MPEG2 -> MPEG4 )

$ ffmpeg -i xxx.mpg \
    -s 1920x1080 \
    -c:v libx264 -tune animation \
    -crf 18 \
    -preset veryslow \
    -c:a copy \
    -movflags faststart \
    yyy.mp4

引数について

Encode/H.264 – FFmpeg]

一部抜粋。

  • -s
    解像度指定
  • -c:v
    動画コーデック。
    H.264 へ変換する際は libx264 を指定。
  • -tune
    映像タイプに応じてチューニングオプションを指定できる。
    見たところ animation が一番頑張ってくれそうな印象だった...
  • -crf
    値が小さいほど画質が高くなる。17~28 がおすすめらしい。

    A lower value generally leads to higher quality, and a subjectively sane range is 17–28.
  • -preset
    エンコード速度・圧縮率のプリセット。エンコード速度を速くするとファイルサイズが大きくなる。
  • -c:a
    音声コーデック。copy を指定すると無変換。
  • -movflags
    faststart を指定すると、ダウンロード完了前に再生可能になるらしい。
  • -vb
    ビットレートの指定。-vb 5000k のように指定すると 5Mbps になる。
  • -filter
    フィルタの指定。-filter:v yadif を指定するとインターレース解除される。自分の環境では無いほうが綺麗だった。

ストリームについて

複数のビデオトラック・オーディオトラックがある場合、どのトラックを用いるか指定することができる。
ffprobe でビデオトラックとオーディオトラックの確認をして、入力に使うストリームを引数 -map で指定。

例えば、ビデオトラックとオーディオトラックが 1つずつしかない場合、下記のように Stream #0:1: Video が 1行表示される。

$ ffprobe sample.mpg
ffprobe version 6.1.1-3ubuntu5 Copyright (c) 2007-2023 the FFmpeg developers
  built with gcc 13 (Ubuntu 13.2.0-23ubuntu3)
  configuration: ... right description omitted ...
  libavutil      58. 29.100 / 58. 29.100
  libavcodec     60. 31.102 / 60. 31.102
  libavformat    60. 16.100 / 60. 16.100
  libavdevice    60.  3.100 / 60.  3.100
  libavfilter     9. 12.100 /  9. 12.100
  libswscale      7.  5.100 /  7.  5.100
  libswresample   4. 12.100 /  4. 12.100
  libpostproc    57.  3.100 / 57.  3.100
Input #0, mpeg, from 'sample.mpg':
  Duration: 00:00:00.02, start: 0.280633, bitrate: 6876 kb/s
  Stream #0:0[0x1bf]: Data: dvd_nav_packet
  Stream #0:1[0x1e0]: Video: mpeg2video (Main), yuv420p(tv, progressive), 720x480 [SAR 32:27 DAR 16:9], 31 fps, 59.94 tbr, 90k tbn
    Side data:
      cpb: bitrate max/min/avg: 9800000/0/0 buffer size: 1835008 vbv_delay: N/A
Unsupported codec with id 98312 for input stream 0

オーディオトラックが 2つ以上ある場合は、複数の Audio 行が表示される。
トラックのカウントは 0 スタートなので、ビデオトラック(全て)・オーディオトラック(2番目)の場合、引数は下記のようになる。

  • # -map 0:v -map 0:a:1
    $ ffmpeg -i "douga.mpg" -s 1920x1080 -tune animation -crf 18 -preset veryslow -c:a copy -movflags faststart -map 0:v -map 0:a:1 "douga.mp4"
  • -map 引数解説
    • 何番目のファイルか
      引数 -i が 1つだけの場合は、常に 0番目となる。
    • ビデオストリーム or オーディオストリーム
      ビデオストリームは v、オーディオストリームは a
    • 何番目のトラックか
      オーディオトラックが複数ある場合は、番号を指定。( 0番目からカウント)。
      ※ビデオトラックが 1つのみの場合は未指定 OK。

      $ ffprobe sample2.mpg
      ffprobe version 6.1.1-3ubuntu5 Copyright (c) 2007-2023 the FFmpeg developers
      built with gcc 13 (Ubuntu 13.2.0-23ubuntu3)
      configuration: ... right description omitted ...
      libavutil      58. 29.100 / 58. 29.100
      libavcodec     60. 31.102 / 60. 31.102
      libavformat    60. 16.100 / 60. 16.100
      libavdevice    60.  3.100 / 60.  3.100
      libavfilter     9. 12.100 /  9. 12.100
      libswscale      7.  5.100 /  7.  5.100
      libswresample   4. 12.100 /  4. 12.100
      libpostproc    57.  3.100 / 57.  3.100
      Input #0, mpeg, from 'sample2.mpg':
      Duration: 00:24:27.85, start: 0.280633, bitrate: 5851 kb/s
      Stream #0:0[0x1bf]: Data: dvd_nav_packet
      Stream #0:1[0x1e0]: Video: mpeg2video (Main), yuv420p(tv, progressive), 720x480 [SAR 32:27 DAR 16:9], 30 fps, 59.94 tbr, 90k tbn
      Side data:
        cpb: bitrate max/min/avg: 9800000/0/0 buffer size: 1835008 vbv_delay: N/A
      Stream #0:2[0x80]: Audio: ac3, 48000 Hz, 5.1(side), fltp, 384 kb/s
      Stream #0:3[0x81]: Audio: ac3, 48000 Hz, 5.1(side), fltp, 384 kb/s
      Unsupported codec with id 98312 for input stream 0

動画ファイルの結合

事前に結合したいファイル名を記載したテキストを用意して、それを引数に結合( concat / concatenate )する。

  • 事前に結合したいファイル名を記載したテキストを用意
    # `mpg-a.mp4` と `mpg-b.mp4` とを結合する場合
    $ cat concat.txt
    file mpg-a.mp4
    file mpg-b.mp4
  • 結合する
    # 結合したファイルを `mpg-ab.mp4` として作成する
    $ ffmpeg -f concat -i concat.txt -c copy mpg-ab.mp4