ffmpeg slideshow with crossfade

I just figured out how to make a slideshow with crossfade. It's a two-step process. The first step reads the pictures with framerate 0.5 (which means 2 seconds for each picture), and produces an intermediate video with framerate 2. That means each picture is repeated 4 times. The second step applies the framerate filter. The result is that each picture is shown for 1.5 seconds, followed by a 0.5 second crossfade.

ffmpeg -framerate 0.5 -i IMG_%3d.jpg -r 2 -codec:v mpeg4 temp.mp4

ffmpeg -i temp.mp4 -vf "framerate=fps=25" -codec:v mpeg4 out.mp4

This two step process works fine, but I have two questions:

  1. Is it also possible to get the same result in one step, without an intermediate video file?
  2. If the answer to the first question is no, can someone please show me how the above commands must be modified for a lossless intermediate file, for example RAWVIDEO?

Thanks, Michael


Solution 1:

You can retime the frames before applying the filter:

ffmpeg -i IMG_%3d.jpg  -vf "setpts=N/0.5/TB,framerate=fps=25" -codec:v mpeg4 out.mp4

Update: The framerate filter appears to be tied to the input framerate at ingest, so an alt method using pipes

ffmpeg -framerate 0.5 -i IMG_%3d.jpg -vf fps=2 -f nut - | ffmpeg -f nut -i - -vf framerate=25 -c:v mpeg4 out.mp4

A single-line workaround:

ffmpeg -i IMG_%3d.jpg -vf zoompan=z=1:d=4:s=WxH:fps=2,framerate=25 -c:v mpeg4 out.mp4

where W and H are replaced with the input dimensions.

Solution 2:

I'd like to summarize the solution:

ffmpeg -i IMG_%3d.jpg -vf zoompan=d=(A+B)/B:s=WxH:fps=1/B,framerate=25:interp_start=0:interp_end=255:scene=100 -c:v mpeg4 -maxrate 5M -q:v 2 out.mp4

where A is the duration in seconds how long each picture is shown (without crossfade duration), B is the crossfade duration in seconds, and WxH is the size of the output video.