ffmpegの備忘録

コロナ禍で講義動画を作成する授業が増えたので,ffmpegを用いて圧縮したり動画の分割結合などを備忘録として残す.

よく使うパラメーター

$ ffmpeg -i input.mp4 -vcodec libx265 -tag:v hvc1 -r 5 -crf 30 output.mp4

google classroomがH.265に対応していることもありH.265で圧縮する.H.264より少しファイルサイズが小さくなる(PCカメラ12GB → 200MB,H.264で圧縮された2GB→200MB).ただし,H.265はエンコードに時間がかかる.動画次第だがCPUエンコード(AMD Ryzen 7 1700 Eight-Core Processor)でcpu使用率1300%でspeed=5~10x.

H.265の場合 -tag:v hvc1 をつけないと macやiosで再生できなかったような気がする.

r:frame/second
crf: 0~51 品質(デフォルトでは23)値が小さいほど高画質

rを大きくするとエンコードに時間がかかる.ためしに-r 15 の場合 speed=2.5x で300MB程度,-r 30 の場合は speed = 1.5x程度 -r 5 の時にファイルサイズは200MBとなる

ffmpeg はGPUエンコーディングに対応しているのでGPUを使えばもっと早いと思うが,手元に対応GPUがない.

同じ設定のでH.264で圧縮する場合は

$ ffmpeg -i input.mp4 -vcodec libx264 -r 5 -crf 30 output.mp4

H265でspeed=5xであるときH264はspeed=10xであったが,ファイルサイズは1.5~2倍程度大きくなる.

複数のファイルを結合して圧縮する

$ ffmpeg -f concat -safe 0 -i file.txt -c:v libx265 -tag:v hvc1 -r 5 -crf 30 output.mp4

ただし,

$ cat file.txt
file ./RPReplay_Final1688195396.MP4
file ./RPReplay_Final1688197352.MP4
file ./RPReplay_Final1688198875.MP4
file ./RPReplay_Final1688200509.MP4

古いversionのffmpegは ffmpeg -i "concat:input1.mpg|input2.mpg|input3.mpg" のようにシングルラインで結合できたが現在はできない模様.

回転する

ipadで画面収録動した動画を再生すると不適切に回転している場合があるので,複数のファイルを結合して90度半時計回りに回転するには

ffmpeg -f concat -safe 0 -i file.txt -vf "transpose=2" -c:v libx265 -tag:v hvc1 -r 10 -crf 30 output.mp4

とすればいい.ここでtranspose フィルターのパラメータは以下の通り

0 = 90度時計回りの回転(+上下反転)
1 = 90度時計回りの回転
2 = 90度反時計回りの回転
3 = 90度反時計回りの回転(+上下反転)

垂直フリップの意味は把握していない.

動画を切り取る

FFMPEG で指定時間でカットするまとめ がわかりやすい.

$ ffmpeg -i input -vcodec libx265 -tag:v hvc1 -r 10 -crf 30 -ss hh:mm:ss -to hh:mm:ss output.mp4

-ss から,-to までの時間の動画にcutしてくれる.hhは省略可能で -ss 10:10 -to 15:20 とすれば動画の10分15秒から15:20秒までの間の動画が(圧縮されて)出力される.

所感

当初はiMovieで動画を結合して書き出して圧縮して,ということをやっていたのでiMovieでの動画の書き出しに膨大な時間を待たされたのちにファイルサイズがでかいので別途ffmpegで圧縮するという無駄な時間が多かったが,上記を駆使すればffmpegだけで概ね完結する.

ハードウェアエンコーディング

debian 12.5からcuda のversionが12.2に上がり,ffmpeg でGPUエンコーディングが利用できるようになった. Nvidia GeForce 1070が利用できるので,ためにしに2Gb程度の動画をh265でハードウェアエンコーディング

$ ffmpeg -i 2024_07_04_08_45_04_Movie.mp4 -c:v hevc_nvenc -tag:v hvc1 -ss 2:30 -r 15 -crf 30 -cq 30 test2.mp4

してみた. speed = 12x 程度を示すとても早く圧縮が終わるのだがファイルサイズが1Gbもある.CPUエンコーティングの場合100-200Mbなので全然違う. パラメーターチューニングすればもっと小さくなるのかもしれないが期待外れである.

結局ハードウェアエンコードってどうなの?(H265篇)