I need to apply crossfade to the last X frames of a video with the first X frames in order to obtain a seamless loop, but making this for the necessary part of video.
Here's the answer for looping the entire video.
Currently what I have: (Whole video duration = 25. Cutted (result) part = 15 sec (from 5 to 20 sec pos). Transition = 1 sec.)
ffmpeg -i input.mp4 -ss 5 -to 20 -filter_complex
"[0]split[body][pre];
[pre]trim=duration=1,format=yuva420p,fade=d=1:alpha=1,setpts=PTS+( (15+(5-1)) /TB)[jt];
[body]trim=1,setpts=PTS-STARTPTS[main];
[main][jt]overlay" -c:v libx264 -preset veryslow -b:v 2500K output.mp4
In this case, everything works, but at the end of the resulting video, a piece from the original video is superimposed, which starts from 0 to 1 second, and not from 4 to 5 seconds of the original video, as it should be.
I read the official ffmpeg documentation, tried some actions on "start/end" parameters for "trim/fade" with changing of "setpts", but I always got just another batch of bugs.
After spending some more time, I decided to start from something easier for understanding (easier logic). I just remove -ss
/-to
and modify the -filter_complex
by spliting the original video into 3 streams, from which I cut out the corresponding parts. The last 2 streams of the same length I have superimposed on each other using the method from my question. After that, I re-combined them in the correct sequence.
(For clarity, I enclosed variables in more and less signs.)
-filter_complex "[0]split=3[var1][var2][var3];
[var1]trim= <cut_start> : (<cut_start> + <duration> - <fade_time>),setpts=PTS-STARTPTS[v0];
[var2]trim= (<cut_start> + <duration> - <fade_time>) : (<cut_start> + <duration>),setpts=PTS-STARTPTS[v1];
[var3]trim= (<cut_start> - <fade_time>) : <cut_start> ,format=yuva420p,fade=start_time= (<cut_start> - <fade_time>) :duration= <fade_time> :alpha=1,setpts=PTS-STARTPTS[v2];
[v1][v2]overlay[v3];
[v0][v3]concat=n=2:v=1:a=0[out]" -map "[out]"