4

I have ffmpeg 2.1.4 and an input movie in.mkv. There are effectively 2 different scenes inside of in.mkv. I want to be able to crossfade between the scenes, preferably with just using a complex filter instead of external programs. Essentially, I want to have something like an overlay but with the alpha changing at a specific time.

Consider if in.mkv looked like this:

00:00 - 00:05 scene 1
00:05 - 00:10 junk
00:10 - 00:15 scene 2

So, I would want an output that had:

00:00 - 00:04 scene 1 (0-4)
00:04 - 00:05 alpha fading between scene 1 (4-5) and 2 (10-11)
00:05 - 00:09 scene 2 (11-15)

I see that there's a filter for: overlay, alphamerge, and color, but it's not clear how exactly to do this.

In general, it seems hard to work with pieces of a movie file in ffmpeg. Is there a way to say that I am taking various pieces of the same input file and putting them together without rendering them as separate movies first?

0

1 Answer 1

6

I got it to work like this:

ffmpeg -f lavfi -i testsrc -ss 6 -f lavfi -i testsrc -filter_complex "
  color=white,fade=out:st=4:d=1[alpha];
  [0:v][alpha]alphamerge[am];
  [1:v][am]overlay=0:0
" -t 9 b.mkv

So, I have the same movie as 2 different inputs, but seek to the time difference, and use a fade out on white to generate the alpha channel, then blend that together with overlay to crossfade. (I suspect it would also be possible to use geq.)

There is an additional complication. If you seek before doing the crossfade, you must make sure you seek to right after a frame (so specify when that frame should happen + 1 ms) otherwise you risk having the destination rounding to having a frame before the source, causing a very noticeable flicker at the beginning of the fade.

Also, if there's audio streams as well, they can be crossfaded by adding to the filter:

[0:a]afade=out:d=2[a1];
[1:a]afade=in:d=2[a2];
[a1][a2]amix=inputs=2,volume=2

You have to increase the volume to compensate for amix decreasing the volume.

Though, this still seems more complicated than it ought to be. Also, would this require decoding the video twice and rendering a bunch of frames that will never be seen?

Not the answer you're looking for? Browse other questions tagged or ask your own question.