8

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

MarianD
  • 2,666
  • 1
  • 17
  • 26
Michael
  • 133
  • 1
  • 7
  • 1
    Any reason you need `mpeg4` as codec? Using that particular encoder without setting any target bitrate or quality level will result in bad quality output. I'd rather use H.264 unless you specifically need to target a device that does not support it. – slhck Nov 05 '17 at 18:58
  • I did omit the bitrate and quality level settings in the above example, because I wanted to keep it as short as possible. – Michael Nov 05 '17 at 19:18

2 Answers2

5

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.

Michael
  • 133
  • 1
  • 7
  • `-b:v 5M` and `-q:v 0` are mutually exclusive; either you want a particular bitrate (but then two-pass encoding would be better), or you specify a target quality level (´-q:v 0` would however result in a very large file). – slhck Nov 06 '17 at 12:09
  • Doesn't the specified bitrate work only as a maximum in this case? I think when both parameters are specified, it means use the specified quality, but do not exceed the specified bitrate. – Michael Nov 06 '17 at 12:15
  • No, that's the `-maxrate` parameter. If you really need `mpeg4`, use `-q:v 2 -maxrate 5M` for a 1080p video, for example, to achieve a limited rate VBR stream. – slhck Nov 06 '17 at 12:36
  • Why does this command cause me to overwrite the my image files? Also this command keeps creating syntax errors in shell. I think you're missing some quotes. And if I do add quotes around the command, it keeps asking to overwrite files. – CMCDragonkai Oct 21 '19 at 03:57
  • This command has only one output file "out.mp4" and won't overwrite any of your image files. – Michael Oct 22 '19 at 04:18
  • This does not work at all. I get a maybe 3 of my images with one crossfade, the other several hundred are not in the video and it's 6 seconds long... – jjxtra Feb 18 '23 at 05:15
  • For me it works. See chapter 2.4 in http://www.astro-electronic.de/FFmpeg_Book.pdf – Michael Feb 19 '23 at 08:48
3

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.

Gyan
  • 34,439
  • 6
  • 56
  • 98
  • But this doesn't do the same thing. It produces a video where the crossfade duration is 2 seconds, and when one crossfade ends, the next crossfade begins immediately. – Michael Nov 05 '17 at 12:21
  • Workaround added – Gyan Nov 05 '17 at 14:31
  • ok, I understand what you mean. First apply the fps filter and then the framerate filter. But I'm calling ffmpeg from a Windows batch file. I think in this case I must write the commands in two lines and use an intermediate file. – Michael Nov 05 '17 at 19:22
  • Why? You can apply the workaround in a batch file. – Gyan Nov 05 '17 at 19:51
  • It doesn't work. When I start the batch file, the cmd.exe window opens and closes immediately. This is the content of my batch file: c:/ffmpeg/ffmpeg -framerate 0.5 -i IMG_%%3d.jpg -vf fps=2 -f nut - | c:/ffmpeg/ffmpeg -f nut -i - -vf framerate=25 -c:v mpeg4 out.mp4 pause – Michael Nov 05 '17 at 20:29
  • the pause command is in a new line – Michael Nov 05 '17 at 20:33
  • The single-line workaround with zoompan filter works great! There is a small typo in it, replace "d:4" by "d=4" Thank you very much! – Michael Nov 06 '17 at 09:30
  • "-framerate 0.5" at the beginning can be omitted. "z=1" can also be omitted, it's the default value. – Michael Nov 06 '17 at 09:35
  • I am confused. None of these options work. I get a slideshow that mostly shows the first image, rapidly changes to the second and then the other hundred or so are missed and my video is only 6 seconds long... – jjxtra Feb 18 '23 at 05:20