GoProで撮影したタイムラプスのフレームレートをFFmpegで良い感じにする

この前GoPro HERO11 Blackを買った。数時間の何かを記録するとき、普通に動画を録画すると、バッテリーもSDカードの容量もPCのストレージもすぐに尽きてしまう。そういうときにタイムラプスが有用。タイムラプスとは、本来は写真を繋いで動画にしたものらしいけど、普通に動画として撮影しているので、単に10倍速とか20倍速とかの早回しの動画。

1個問題があり、GoProのタイムラプスは25 fpsで撮影される。PCのモニターは一般的には60 fpsなので、これに合わせたフレームレートにしたい。また、なるべく情報が残っていたほうが良いので10倍速で撮影するけれど、Twitterに投稿するときなどにはもっと早くしたい。このとき、中途半端な速度にするのではなく、残るフレームが一定の間隔になってほしい。まあ、25 fpsだったり残るフレームの間隔が一定でなかったりして気になるかというと、そこまで気にならない気はする。自己満足ではある。

動画編集ソフトを使うのではなくFFmpegでお手軽に変換したい。フレームレートの変換とフレームの間引きが混じってややこしいので、メモしておく。

フレームレートの変換の色々は、このページが詳しい。

nico-lab.net

ffmpeg -r 240 -i GX012345.MP4 -f lavfi -i aevalsrc=0 -map 0:0 -map 1:0 -shortest -vf framerate=60 -s 1920x1080 -b:v 100M output.mp4

というコマンドが良いのではないだろうか。 240 の部分は、60の倍数で適切な値にする。240で、元々のフレームレートの 240/25 = 9.6 倍になる。

以降は各オプションの意味。なお、一般的にLinuxのコマンドはオプションの順番に意味は無いが、FFmpegの場合は意味がある。位置によって、そのオプションが入力に対して効くのか、出力に対して効くのかが変わる。

-r 240

変換元の動画が25 fpsのところ、240 fpsという扱いにする。フレームの間引きはされない。動画の長さが 25/240 になる。

-i GX012345.MP4

変換元の動画。ファイル名は動画に合わせて変える。

-f lavfi -i aevalsrc=0

無音の音声を作る。

-map 0:0 -map 1:0

0番目(0始まり)の動画( -i GX012345.MP4 )の0番目のトラック(GoProで撮影した動画では映像)と、1番目の動画の0番目のトラック( -f lavfi -i aevalsrc=0 で作った無音の音声)を組み合わせて、次に流す。

-shortest

音声と映像の短いほうが終わったら、動画全体の映像を終了する。 -f lavfi -i aevalsrc=0 は無音の音声を作り続けるので、これを付けないと終わらない。

この辺のオプションを付けずに音声がそのままだと、映像が短くなるのに音声が元の長さのままで、最後のほうが音声だけになってしまう。GoProで撮影したタイムラプスには無音の音声が付いているので、別途無音の音声を生成したりせず、単に -shortest を付けるだけでも良さそうだが、なぜか上手くいかなかった。このチケットの話と関係がある? 謎。

trac.ffmpeg.org

無音の音声を付ける意味

なぜ無音なのに音声トラックを付けるの? 音声トラックを消してしまっても良いのでは? という話。上の3個のオプションの代わりに -an を付ければ音声トラック無しの動画になる。問題が無いならそれでも良い。動画を投稿したり編集したりするときに、映像のみの動画だとトラブルことがある。だから、GoProも無音の音声を付けているのだと思う。

-vf framerate=60

フレームの間引きによってフレームレートを60 fpsにする。 -r 240 にした場合は4フレーム中3フレームが消えることになる。

-s 1920x1080

どうせなら高解像度のほうが良いと思って4K(3840x2160)で撮影していたのをFullHD(1920x1080)に変換。撮影するときにFullHDにしていたり、出力も4Kにしたりするなら不要。

-b:v 100M

フレームレート。100 Mbps。適当に大きなビットレートにしている。FullHDの場合は10 Mbps、4Kで20 Mbpsくらいあれば、画質が気になることはないのではなかろうか。ファイルサイズが気になるなら適当に調整。動画の長さは元の動画の 25/240 になる。ビットレートはビットで、ファイルサイズはバイトであり、8倍違うことに注意。

output.mp4

ファイル名。適当に。

コンテナ、コーデック

MP4やMKVなどのコンテナフォーマットは出力ファイル名の拡張子から決められる。

コーデックはデフォルトではH.264(コンテナによって変わる?)。エンコードに時間が掛かるし、対応していないこともあるし、現状ではH.265にしなくても良いのではと思うが……H.265にするなら、 -vcodec libx265 を付ける。

なお、GoPro 11はH.264で録画することはできず、H.265のみになってしまった。(特許の問題で)H.265は全然普及しないと言われ続けていたけれど、世の中はじわじわとH.265に移りつつあるのかもしれない。