I have a (random selection) of JPG images that I want to use to make into an APNG animation using ffmpeg (to test the process). They are all the same dimensions (256x256). But I cannot seem to get the correct syntax to control the frame delay and loop control (to loop forever). Is it possible to set these parameters using ffmpeg when creating an APNG from a sequence of images? If so, can someone provide the proper syntax and/or show an example command? I have searched the ffmpeg documentation and cannot seem to find relevant syntax.
I can do the following, but it will not accept -delay nor -loop. I use Imagemagick to pipe in the images.
This works, but does not loop, and runs very fast.
magick lena.jpg mandril3.jpg monet2.jpg zelda1.jpg PNG:- | ffmpeg -i - x.apng
This gives errors about delay and/or loop:
magick lena.jpg mandril3.jpg monet2.jpg zelda1.jpg PNG:- | ffmpeg -i - -delay 1000 -loop -1 x.apng
I am also curious to know if it is possible to specify a sequence of images directly in ffmpeg as input without using ImageMagick.
Sorry, I am a relative novice with ffmpeg. I am using ffmpeg 4.2.1.
You can set looping with the -plays
output option. 0
is infinite, 1
is no loop, 2
will play twice, etc.
-plays
is an option specific (aka a private option) for the APNG muxer. You can see private options for a specific muxer with ffmpeg -h muxer=apng
. See What are all codecs and formats supported by FFmpeg? for more examples.
Another private option for APNG is -final_delay
to force delay after the last frame. Accepts a value in seconds.
The most common method is to use the image demuxer.
It accepts a numbered sequence such as image_001.png
, image_002.png
, etc:
ffmpeg -framerate 3 -i image_%03d.png -plays 0 output.apng
Or a glob (at least on Linux & macOS):
ffmpeg -framerate 1 -pattern_type glob -i "*.png" output.apng
Set delay/timing with the -framerate
input option as shown in the examples above. This is a private option of the image demuxer.
You can pipe the images to ffmpeg
like you do in your question. Can be useful in combination with other tools to provide the order you prefer.
For example, using sort
is helpful your image series uses natural/version numbering such as 1.png
, 2.png
, ..., 10.png
, etc. Otherwise ffmpeg
would order them as 1.png
, 10.png
, 2.png
.
cat $(find . -name '*.png' -print | sort -V) | ffmpeg -framerate 1 -i - -plays 1 output.apng
Or use the concat demuxer if you want to provide a list of files. Each image can have its own duration.
Create input.txt
containing:
file 'lena.jpg'
duration 1
file 'mandril3.jpg'
duration 0.5
file 'monet2.jpg'
duration 3
file 'zelda1.jpg'
duration 2
Duration value is in seconds.
Concatenate:
ffmpeg -f concat -i input.txt -plays 0 output.apng
If you omit duration
, and want an even delay/timing between images you can use the -r
input option. This example will play at 1 frame per second.
ffmpeg -r 1 -f concat -i input.txt -plays 0 output.apng
Also see FFmpeg Wiki: Concatenate.