Is there a way to use ffmpeg to halt a video for 3 seconds every 10 seconds?
For example, I use a 30 seconds video, the video should stop at 0:00, 0:10, 0:20 and 0:30 for 3 seconds. The length of the output video is 0:42 seconds.
Thank you!
Answer
Edit: Different method added, which accounts for audio and also the overwritten frames due to the initial method,which is shown at the bottom.
ffmpeg -i input.mp4 -filter_complex \
"[0:v]split=4[v0][v1][v2][v3]; \
[v0]trim=start_frame=0:end_frame=1,loop=90:1:0,setpts=N/FRAME_RATE/TB[0v]; \
[v1]trim=start_frame=1:end_frame=301,loop=90:1:299,setpts=N/FRAME_RATE/TB[1v]; \
[v2]trim=start_frame=301:end_frame=601,loop=90:1:299,setpts=N/FRAME_RATE/TB[2v]; \
[v3]trim=start_frame=601:end_frame=900,loop=90:1:298,setpts=N/FRAME_RATE/TB[3v]; \
aevalsrc=0:d=3[0a]; \
[0:a]asplit=3[a1][a2][a3]; \
[a1]atrim=0:10,asetpts=N/SR/TB[1a]; \
[a2]atrim=10:20,asetpts=N/SR/TB[2a]; \
[a3]atrim=20:30,asetpts=N/SR/TB[3a]; \
[0v][0a][1v][1a][2v][2a][3v][3a]concat=n=4:v=1:a=1[v][a]" \
-map "[v]" -map "[a]" outva.mp4
This can be done, using a daisychained loop filter.
ffmpeg -i input.mp4 \
-vf loop=90:1:0,setpts=N/FRAME_RATE/TB, \
loop=90:1:390,setpts=N/FRAME_RATE/TB, \
loop=90:1:780,setpts=N/FRAME_RATE/TB, \
loop=90:1:1169,setpts=N/FRAME_RATE/TB
stuttered.mp4
The command above is for a 30 fps video. Each loop filter sets loop to 90 frames i.e. 3 seconds at 30 fps with a 1-frame segment to be looped. The third argument is the frame index that has to be looped. The index for all loop filters after the first, have to be offset since their input feed contains earlier loops inserted e.g. the 2nd loop at 10 seconds would normally be 300 for a 30 fps video, but since the very first has been looped for 3 seconds, it is 3x30 + 10x30 = 390.
The setpts generates a monotonic set of new timestamps after each loop, since otherwise the command doesn't work correctly.
Audio has been completely ignored.
No comments:
Post a Comment