PhilLab
PhilLab

Reputation: 5007

Cross-fade video to itself with FFmpeg for seamless looping

I have found some questions&answers concerning cross-fading between two images or videos, but which ffmpeg CLI commands are needed to fade a video with itself?

Explanation of the desired effect:

Upvotes: 2

Views: 2433

Answers (3)

Dev Null
Dev Null

Reputation: 828

I couldn't get these answers to work. Processing would stop/pause at frame 75 and keep "running" doing nothing.

This answer worked well, and it worked fast for a longer video:

https://stackoverflow.com/a/38189232/901739

Upvotes: 1

camposquinn
camposquinn

Reputation: 126

To expand a little on @llogan's answer using the times I was working with:

-filter_complex "[0]trim=end=1,setpts=PTS-STARTPTS[begin];[0]trim=start=1,setpts=PTS-STARTPTS[end];[end][begin]xfade=wipedown:duration=1:offset=2"

This is almost exactly what I was looking for (fade a video's end into its own beginning for looping) as well, after messing with the filters to figure out what they actually do. First off, here is a slightly clearer explanation of the xfade filter, which is actually super awesome and I'm stoked to know it exists. Try using one of the more dramatic fades to get a clearer picture of your transition.

Breaking down the filtergraph a bit (the timestamps reflect the 4-second video I was looping):

-filter_complex

Call the filtergraph

"[0]trim=end=1,setpts=PTS-STARTPTS[begin];

Taking the first input ([0]) use the trim filter to make the section you want to fade in at the end of the video. Set the end of this excerpt to be at second 1 (it could be whatever, this makes a 1-second exerpt). Then use the setpts filter to set the timestamp (of the excerpt?) to start at zero. [begin] is the arbitrary label for the output of this first filter chain, but you can call it [thomas] or whatever.

[0]trim=start=1,setpts=PTS-STARTPTS[end];

Now use trim to make another input that's actually the entire video, minus the same 1 second that you'll be fading into at the end. This tripped me up a bit until I realized you're setting the end of the first chunk at the same point of the start of the main chunk. This main chunk gets the label [end].

[end][begin]xfade=fade:duration=1:offset=2"

Now use the xfade filter using the fade mode (there are examples of all the others in the link above) to dissolve from [end] into [begin]. You set the duration of the fade to last 1 second and offset the beginning of the fade at the 2 second mark. Keep in mind, this was a 4-second video that just got the first second basically trimmed and overlaid onto the end, so you now have a 3-second video. You could just as easily left the [end] chunk starting at 0 as well (the OP asked for what's described here tho).

Give it an output.mov path and you're good to go.

Upvotes: 7

llogan
llogan

Reputation: 133973

Use the trim, setpts, and xfade filters:

ffmpeg -i input.mp4 -filter_complex "[0]trim=end=1,setpts=PTS-STARTPTS[begin];[0]trim=start=1,setpts=PTS-STARTPTS[end];[end][begin]xfade=fade:duration=0.5:offset=8.5" output.mp4

Upvotes: 3

Related Questions