今まで ffmpeg は異なるフレームレートの動画を1つに出力するのはできないと思っていたが、あらかじめ異なるフレームレートにエンコードしておいて、その後に連結すれば VFR の動画になる。
方法は以前書いた demuxer の concat を使えば楽に VFR の動画になる。注意点は映像音声ともに同じコーデックで同じエンコード設定、音声は同じサンプリング数であること。ただし動画によっては「Non-monotonous DTS in output stream 0:0」のエラーが出るが再生して問題なかったら気にしない。エラーが気になるときは入力オプションに-fflags +igndtsをつけてremuxする。
ffmpeg -fflags +igndts -i input.ts -c:v copy tmp.mp4 ffmpeg -i tmp.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts fix.ts
Trim with concat gives issues on the trim point : ffmpeg
または-bsf:a aac_adtstoascをつけてremuxする。
ffmpeg -i input.ts -c:v copy -bsf:a aac_adtstoasc output.mp4
m3u8 – how to fix Non-monotonous DTS in output stream 0:1; when using ffmpeg – Stack Overflow
- concat を使い分ける
- 再エンコードせずに fps を変更する
- ffmpeg で使える映像のテストソース
- ffmpeg でのフレームレート設定の違い
- 【ffmpeg】動画・音声を連結する concat の使い方 其の3
ffmpeg -f concat -safe 0 -i 24-30.txt -c copy vfr.mp4
24-30.txt
file 24p.mp4 file 30p.mp4 file 24p.mp4
動画のパスはシングルクオート”で挟む。
file 'E:/video/24p.mp4' file 'E:/video/30p.mp4' file 'E:/video/24p.mp4'
再生してファイルがおかしい場合は H.264, H.265 の raw コンテナに入れてみる。これでも動画再生アプリでは問題なくてもedgeやchromeなどのブラウザでは正常に再生できないかもしれない。
ffmpeg -i 24p.mp4 -c copy -bsf:v h264_mp4toannexb -an 24p.264
ffmpeg -i 30p.mp4 -c copy -bsf:v h264_mp4toannexb -an 30p.264
映像と音声を合わせる。raw.txtが絶対パスのときは-safe 0を追加する。
ffmpeg -f concat -safe 0 -i raw.txt -f concat -safe 0 -i 24-30.txt -i audio.m4a -map 0:v -map 1:a -c copy vfr.mp4
raw.txt
file 24p.264 file 30p.264 file 24p.264
動画サンプル作成コマンド。
ffmpeg -f lavfi -i testsrc2=r=24000/1001:d=10 24p.mp4
ffmpeg -f lavfi -i testsrc2=r=30000/1001:d=10 30p.mp4