FFmpegで実際使うと便利だが脳みそに焼き付いてくれないオプションメモ

コマンドラインで利用できる動画編集ツールFFmpegですが、十数年来の付き合いだというのに、たまにしか使わないもんだからオプションが脳みそに定着してくれませんw いざ使うとめっちゃ便利なんですよ。でもそこまでたどり着けないw

今回は年貢の納め時と思ってオプションの一覧を自分用にまとめることにします。

ちなみに構成を考えながら動画編集する場合には、素直にAdobe PremiereやFinalCutなどのGUIの編集ソフトを使った方が早いです。FFmpegはあくまで定形処理を行う場合に活躍してくれるものと言えます。

インストール

macOSの場合はHomeBrewで一発です。

$ brew install ffmpeg

WindowsとLinuxは公式サイトに記載があるので参照ください。……大変面倒くさそうですね (´ཀ`」 ∠) trac.ffmpeg.org

ファイル

ファイル形式を変換する

-iで変換元のファイルを指定し、それに続いて出力ファイルを指定するだけ。出力ファイル名の拡張子でフォーマットが決定します。以下ではmovをMP4に変換しています。

$ ffmpeg -i original.mov output.mp4

解像度を変更する

-vfオプションで変換後のサイズを「scale=横幅:高さ」の書式で指定します。以下のように高さに-1を指定するとアスペクト比に応じて自動的に計算してくれます。

$ ffmpeg -i original.mp4 -vf scale=800:-1 output.mp4

横幅と高さのどちらも指定する場合は-sオプションを使います。

$ ffmpeg -i original.mp4 -s 800x600 output.mp4

フレームレートを変更する

-rオプションでフレームレート(FPS)が指定できます。未指定の場合はオリジナルのFPSがそのまま適用されます。

$ ffmpeg -i original.mp4 -r 30 output.mp4

GIFアニメに変換する

先ほどと同じ要領です変換できます。ただGIFアニメは古来からある規格ということもあり動画ファイルと比べると圧縮率が非常に悪いためそのまま変換するとアホみたいに大きなファイルになってしまいます。(現代では特別な事情がなければGIFアニメよりもMPEGなどの動画ファイルにした方が圧倒的に扱いやすいです)

そこでまずは-rオプションでフレームレートを低めに指定します。

$ ffmpeg -i original.mp4 -r 10 output.gif

試しに手元にあったH.264でエンコードされた50fps、約5.3Mbyteのファイルを上記コマンドで変換したところ、約58Mbyteまで膨れ上がりました。なんと10倍ですw

解像度とシーンを指定する

以下のように解像度を小さくする、時間を指定し切り抜き最小限のシーンに収めるなども考慮した方が良さそうですね。

$ ffmpeg -i original.mp4 -r 10 -s 320x240 -ss 00:00:00 -to 00:00:30 output.gif

ループ回数

最後まで再生したあとの動作を-loopオプションで指定することもできます。未指定時は0です。

$ ffmpeg -i original.mp4 -r 10 -loop 0 output.gif
意味
-1 ループしない(停止する)
0 無限ループ
整数 指定した回数分ループする

その他

カラーパレットを作り直すことでキレイなGIFアニメに変換する方法もあるそうです。

動画編集

指定したシーンを切り出す

以下で開始5分から3分間の映像を切り出します。

$ ffmpeg -i original.mp4 -ss 00:05:00 -to 00:08:00 output.mp4

-toの箇所は-t (秒数)とすることで開始時間からの経過秒数を指定することもできます。また-ss 00:05:00の部分を-iよりも前に記述するとちょっとだけ高速になるそうです。

-c copyを付けて無圧縮(エンコードなし)で実行したい場合があると思いますが、残念ながら動画や音声がずれてしまうケースがあります。その場合は諦めてオプションを外しエンコードしてやると解消されたりします。敗北感がありちょっと悔しいですがw ここらへんはFFMpeg側でがんばって欲しいですね。

指定した領域を切り出す

以下で左上を基準(=0)として横幅50、高さ50ピクセルの動画を切り出すことができます。いわゆる「クロップ」ですね。xとyを省略すると動画の中央が基準となります。

$ ffmpeg -i original.mp4 -vf crop=w=50:h=50:x=0:y=0 output.mp4

画像を上に載せる

例えばコピーライト的なものを載せたりできます。透過PNGなどを指定すると、透過部分がちゃんと透過され後ろにある動画が見えます。

$ ffmpeg -i original.mp4 -loop 1 -i image.png -filter_complex 'overlay=x=(W-w)/2:y=(H-h)/2:shortest=1' -c:a copy output.mp4

場所を指定するオプション部分は以下のように指定できます。大文字W(H)が画面サイズ、小文字w(h)が画像サイズに。整数を指定すると直接動画上の座標になるようです。

場所 オプション
中央 overlay=x=(W-w)/2:y=(H-h)/2
左上 overlay=x=1:y=1
右上 overlay=x=(W-w):y=1
右下 overlay=x=(W-w):y=(H-h)
左下 overlay=x=1:y=(H-h)

テキストを上に載せる

$ ffmpeg -i original.mp4 -filter_complex "drawtext=fontfile=/System/Library/Fonts/Menlo.ttc:text=Hello" output.mp4
項目 説明
fontsize=16 文字の大きさ
fontcolor=black 文字色
x=0:y=0 文字を配置する座標

macOSの場合、フォントファイルは以下の場所にあります。

システムフォント
/System/Library/Fonts
ライブラリフォント
/Library/Fonts
ユーザーフォント
/Users/(ユーザ名)/Library/Fonts

音声

動画に音声を追加する

-iオプションで元となる動画と音声ファイルを指定します。

$ ffmpeg -i original.mp4 -i audio.wav output.mp4

注意点としては既存の音声と入れ替わる点です。サイトによってはオプションに-map 0:v:0 -map 1:a:0を付けることで、既存の音声に追加することができると解説がありますが、手元の環境では残念ながら再現できませんでした。うーむ 🤔

動画の音量を調整する

-af volume=(調整後の値)といった形で指定します。1.0を基準値として0.5なら半分、2.0なら倍になります。

$ ffmpeg -i original.mp4 -vcodec copy -af volume=0.1 output.mp4

volume=5dBのように数値に続けて単位を付けるとデシベルでの指定も可能です。

動画から音声を取り出す

音声フォーマットの拡張子を指定して出力するだけです。

$ ffmpeg -i original.mp4 audio.mp3

ただし元動画と違う音声フォーマットを指定すると圧縮される場合があります。そのまま無圧縮の状態で取り出したい場合は、-iオプションを指定し音声フォーマットを事前に確認しそのままの形式で出力してやります。以下の例ではAudio: aacとあるようにAAC形式であることがわかります。

$ ffmpeg -i original.mp4
(中略)
  Duration: 00:00:47.03, start: 0.000000, bitrate: 201 kb/s
    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1920x1080 [SAR 1:1 DAR 16:9], 82 kb/s, 6 fps, 6 tbr, 12288 tbn, 12 tbc (default)
    Metadata:
      handler_name    : VideoHandler
    Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 116 kb/s (default)
    Metadata:
      handler_name    : SoundHandler

あとは元動画の音声フォーマットを指定して出力するわけですが、-vn -acodec copyを追加で付ける必要があります。

$ ffmpeg -i original.mp4 -vn -acodec copy audio.m4a

動画から音声を削除する

音声だけを削除した動画も作成できます。

$ ffmpeg -i original.mp4 -vcodec copy -an output.mp4

静止画

連続でスクショを撮る

1秒間に4枚ずつ(250ミリ秒毎に1回)静止画を作成しjpegフォルダに連番で保存します。-rオプションを変更することで1秒あたりの撮影枚数を変更できます。また「%02d」の箇所を変更すると連番の桁数が調整できます。うっかりミスですごい枚数になってしまう場合があるので、今回のように専用のフォルダを作成しその中に保存するのがおすすめです。

$ ffmpeg -i original.mp4 -r 4 -vcodec mjpeg jpeg/ss_%02d.jpg

PNG形式で出力したい場合は-vcodec pngを指定します。

-ss-toとのあわせ技で指定したシーンのみを対象とすることも可能です。

$ ffmpeg -i original.mp4 -r 4 -vcodec mjpeg -ss 00:01:00 -to 00:01:30 jpeg/ss_%02d.jpg

静止画を動画にする

上で撮ったスクショを逆に動画に変換してみます。

$ ffmpeg -framerate 4 -i jpeg/ss_%02d.jpg -vcodec libx264 -pix_fmt yuv420p -r 60 output.mp4

最初の-framerateは画像を切り出した際のフレームレート。最後の-rもフレームレートの指定ですが、こちらは出力する動画の物です。つまりここでは4FPSで切り出した画像を60FPSの動画にしています。

応用するとWebカメラ等で定期的に撮影した画像を、タイムラプス動画にすることもできそうですね。

参考ページ