PTSを変更することで再生速度を上げたり下げたり、複数のファイルを合わせたりするときにPTSを揃えたりするのに使うsetpts、asetpts
フィルタの使い方。音声の速度変更にはrubberband
フィルタを使う方法もある。
サンプリング周波数を変えずにテンポとピッチを変える rubberband
FFmpeg 7.0からsetpts
フィルタを通して映像を出力するとフレームレートが25に上書きされるので、fps
フィルタか、出力オプションの-rとfps数、または-fps_mode passthroughを追加する。
Ffmpeg: concatenate videos and keep framerate the same – Super User
24000/1001 fpsで出力する例。
-vf setpts=PTS-STARTPTS,fps=24000/1001
-vf setpts=PTS-STARTPTS -r 24000/1001
lavf/vf_setpts: unset output framerate · FFmpeg/FFmpeg@f121d95 · GitHub
アニメGIFの速度調整は-itsscaleで1/倍速を小数で指定する。
再エンコードせずに fps を変更する
ためになる話 – MP4, DTS, CTS, priming samples, 古のハック pic.twitter.com/y1SGCZ5jgr
— fueruwakame (@wakame_2012) February 28, 2023
CTS(Composition Time Stamp)について。
timestamp – Different PTS values in ffmpeg and MP4 CTS values obtained using ctts and stts – Stack Overflow
ffmpeg 4.4からはビットストリームフィルタでPTSを書き換えられるようになったので再エンコードコード不要で映像の再生速度を変更できる。
ffmpeg -i input -af "atempo=2" -bsf:v setts=ts=TS/2 -c:v copy output
出力フレームレートを29.97fpsに変更する。
ffmpeg -i video -bsf:v setts=dts=N/((30000/1001)*TB):pts=PTS+N/((30000/1001)*TB)-DTS -c:v copy output
公式ドキュメント:FFmpeg Bitstream Filters Documentation : setts
基本コマンド
PTSを0リセットする。
ffmpeg -i input -filter_complex setpts=PTS-STARTPTS -c:a copy output
再生速度を2倍にする。
ffmpeg -i input -filter_complex setpts=(PTS-STARTPTS)/2;atempo=2 output
再生速度を半分にする。
ffmpeg -i input -filter_complex setpts=2*(PTS-STARTPTS);atempo=0.5 output
2つの映像のPTSをリセットして縦に並べる。
ffmpeg -i input1 -i input2 -filter_complex [0:v]setpts=PTS-STARTPTS[v0];[1:v]setpts=PTS-STARTPTS[v1];[v0][v1]vstack output
公式ドキュメント:FFmpeg Filters Documentation : setpts, asetpts
オプション
評価式のオプション
- FRAME_RATE, FR
フレームレート。固定フレームレートだけを定義する。固定値。音声はNaN - PTS
PTS(Presentation Timestamp)秒。PTS*TBでよく見る秒時間になる - N
0から始まる映像フレーム数、または音声サンプル数 - NB_CONSUMED_SAMPLES
累積の音声サンプル数 - NB_SAMPLES, S
音声サンプル数。固定値 - SAMPLE_RATE, SR
音声のサンプリング周波数 - STARTPTS
入力したストリームの開始時のPTS時間 - STARTT
入力したストリームの開始時の時間 - INTERLACED
現在のフレームがインターレースかどうか。インターレースなら1。そうでなければ0 - T
現在のフレームの秒時間 - POS
読み込み位置でのバイトサイズ。分からなければ未定義になる - PREV_INPTS
1つ前フレームのPTS - PREV_INT
1つ前フレームのT - PREV_OUTPTS
- PREV_OUTT
- RTCTIME
RTC のマイクロ秒。現在は非推奨。代わりに time(0) を使う - RTCSTART
RTC のマイクロ秒。マイクロ秒で動く - TB
タイムスタンプのタイムベース。固定値
応用例
PTSを25fpsに修正する。映像がそれよりも高fpsなら再生速度が遅くなり、低fpsなら再生速度が速くなる。select
フィルタなどで連続しない特定フレームで出力するときなどにも使う。
ffplay -f lavfi -i testsrc2=r=60,setpts=N/(25*TB)
ffplay -f lavfi -i testsrc2=r=10,setpts=N/(25*TB)
特定の映像フレームや音声サンプルを出力するselect, aselect
開始PTSを10秒進める。用途は動画の開始PTSが0開始でない場合に修正する。利用例。
setpts=PTS+10/TB
trim, atrim
フィルタで10秒から20秒までカットする。
trim=10:20,setpts=PTS+10/TB;atrim=10:20,asetpts=PTS+10/TB
フレーム数から現在のタイムスタンプ秒に変換しタイムスタンプを振り直す。一部をカットしてフレームレートを変えない時に使う。
setpts=N/FRAME_RATE/TB
音声サンプル数から現在のタイムスタンプ秒に変換しタイムスタンプを振り直す。一部をカットしてサンプルレートを変えない時に使う。
asetpts=N/SR/TB
タイムスタンプを振り直すのはtrim、select、segment
フィルタなどで複数に分割、特定フレームだけ出力する場合に使う。振り直さなければ元映像のPTSで分割されるので、出力されなかった映像は動かなくなる。
ffmpeg -i input -an -vf select=eq(pict_type\,I) -vsync 0 -t 5 output.mp4
ffmpeg -i input -an -vf select=eq(pict_type\,I),setpts=N/FRAME_RATE/TB -vsync 0 -t 5 output.mp4
動画の途中、ここでは10秒から12秒までをカットして前後をつなげる。
ffmpeg -i input -vf select='not(between(t\,10\,12))',setpts=N/FRAME_RATE/TB -af aselect='not(between(t\,10\,12))',asetpts=N/SR/TB output
25fpsから60fpsにフレーム落ちせずに再生速度を2.4倍にする。
settb=1/6000,setpts=PTS/2.4
ffmpeg speed up video from 25 to 60 fps dropping frames – Stack Overflow
10秒以内は3秒のオフセットを追加して、10秒以降は入力と同じPTS。
asetpts='if(lt(N\,10)\,PTS+3/TB\,PTS)'
How to use FFmpeg to adjust the audio pts of specific frames – Stack Overflow
部分的に速度を変えるには映像はtrim
フィルタでカットしてsetpts
フィルタで速度を変えて、音声はatrim
フィルタでカットしてatempo、rubberband
フィルタで速度を変えてconcat
フィルタでつなげる。
ffmpeg -i Soon.mp4 -filter_complex "[0:v]trim=0:2,setpts=PTS-STARTPTS[v1];[0:v]trim=2:5,setpts=2*(PTS-STARTPTS)[v2];[0:v]trim=5,setpts=PTS-STARTPTS[v3];[0:a]atrim=0:2,asetpts=PTS-STARTPTS[a1];[0:a]atrim=2:5,asetpts=PTS-STARTPTS,atempo=0.5[a2];[0:a]atrim=5,asetpts=PTS-STARTPTS[a3];[v1][a1][v2][a2][v3][a3]concat=n=3:v=1:a=1" -preset superfast -profile:v baseline output.mp4
trim=10:20,setpts=PTS+10/TB;atrim=10:20,asetpts=PTS+10/TB
はあ、trimフィルタはPTSをいじらないから、開始秒は20秒になるのか