Make Animated AVIFs (Instead of GIFs) With FFmpeg
Scratch Notes
These are scratch notes while I'm figuring out how to get things working. Feel free to play along at home. Just keep in mind that things are still very much in flux.
#!/bin/bash
| \
| \
|
Output:
Process took to long and was halted
ffmpeg version 7.1.1 Copyright (c) 2000-2025 the FFmpeg developers
built with Apple clang version 16.0.0 (clang-1600.0.26.6)
configuration: --prefix=/opt/homebrew/Cellar/ffmpeg/7.1.1_2 --enable-shared --enable-pthreads --enable-version3 --cc=clang --host-cflags= --host-ldflags='-Wl,-ld_classic' --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libaribb24 --enable-libbluray --enable-libdav1d --enable-libharfbuzz --enable-libjxl --enable-libmp3lame --enable-libopus --enable-librav1e --enable-librist --enable-librubberband --enable-libsnappy --enable-libsrt --enable-libssh --enable-libsvtav1 --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvmaf --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libspeex --enable-libsoxr --enable-libzmq --enable-libzimg --disable-libjack --disable-indev=jack --enable-videotoolbox --enable-audiotoolbox --enable-neon
libavutil 59. 39.100 / 59. 39.100
libavcodec 61. 19.101 / 61. 19.101
libavformat 61. 7.100 / 61. 7.100
libavdevice 61. 3.100 / 61. 3.100
libavfilter 10. 4.100 / 10. 4.100
libswscale 8. 3.100 / 8. 3.100
libswresample 5. 3.100 / 5. 3.100
libpostproc 58. 3.100 / 58. 3.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'initial.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf61.1.100
Duration: 00:00:06.17, start: 0.000000, bitrate: 881 kb/s
Stream #0:0[0x1](und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709, progressive), 1072x912 [SAR 1:1 DAR 67:57], 877 kb/s, 23.98 fps, 23.98 tbr, 24k tbn (default)
Metadata:
handler_name : VideoHandler
vendor_id : [0][0][0][0]
encoder : Lavc61.3.100 libx264
timecode : 01:00:00:00
Stream #0:1[0x2](eng): Data: none (tmcd / 0x64636D74), 0 kb/s
Metadata:
handler_name : VideoHandler
timecode : 01:00:00:00
Stream mapping:
Stream #0:0 -> #0:0 (h264 (native) -> av1 (libaom-av1))
Press [q] to stop, [?] for help
[libaom-av1 @ 0x13de05b00] 3.12.1
[libaom-av1 @ 0x13de05b00] Neither bitrate nor constrained quality specified, using default CRF of 32
Output #0, avif, to 'output.avif':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf61.7.100
Stream #0:0(und): Video: av1 (av01 / 0x31307661), yuv420p(tv, bt709, progressive), 1072x912 [SAR 1:1 DAR 67:57], q=2-31, 23.98 fps, 24k tbn (default)
Metadata:
handler_name : VideoHandler
vendor_id : [0][0][0][0]
timecode : 01:00:00:00
encoder : Lavc61.19.101 libaom-av1
Side data:
cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: N/A
frame= 0 fps=0.0 q=0.0 size= 0KiB time=N/A bitrate=N/A speed=N/A
frame= 0 fps=0.0 q=0.0 size= 0KiB time=N/A bitrate=N/A speed=N/A
frame= 0 fps=0.0 q=0.0 size= 0KiB time=N/A bitrate=N/A speed=N/A
frame= 0 fps=0.0 q=0.0 size= 0KiB time=N/A bitrate=N/A speed=N/A
frame= 0 fps=0.0 q=0.0 size= 0KiB time=N/A bitrate=N/A speed=N/A
frame= 0 fps=0.0 q=0.0 size= 0KiB time=N/A bitrate=N/A speed=N/A
frame= 0 fps=0.0 q=0.0 size= 0KiB time=N/A bitrate=N/A speed=N/A
frame= 0 fps=0.0 q=0.0 size= 0KiB time=N/A bitrate=N/A speed=N/A
frame= 0 fps=0.0 q=0.0 size= 0KiB time=N/A bitrate=N/A speed=N/A
frame= 0 fps=0.0 q=0.0 size= 0KiB time=N/A bitrate=N/A speed=N/A
frame= 0 fps=0.0 q=0.0 size= 0KiB time=N/A bitrate=N/A speed=N/A
frame= 0 fps=0.0 q=0.0 size= 0KiB time=N/A bitrate=N/A speed=N/A
frame= 0 fps=0.0 q=0.0 size= 0KiB time=N/A bitrate=N/A speed=N/A
frame= 0 fps=0.0 q=0.0 size= 0KiB time=N/A bitrate=N/A speed=N/A
frame= 0 fps=0.0 q=0.0 size= 0KiB time=N/A bitrate=N/A speed=N/A
frame= 0 fps=0.0 q=0.0 size= 0KiB time=N/A bitrate=N/A speed=N/A
frame= 0 fps=0.0 q=0.0 size= 0KiB time=N/A bitrate=N/A speed=N/A
frame= 0 fps=0.0 q=0.0 size= 0KiB time=N/A bitrate=N/A speed=N/A
frame= 0 fps=0.0 q=0.0 size= 0KiB time=N/A bitrate=N/A speed=N/A
frame= 0 fps=0.0 q=0.0 size= 0KiB time=N/A bitrate=N/A speed=N/A
frame= 0 fps=0.0 q=0.0 size= 0KiB time=N/A bitrate=N/A speed=N/A
frame= 0 fps=0.0 q=0.0 size= 0KiB time=N/A bitrate=N/A speed=N/A
frame= 0 fps=0.0 q=0.0 size= 0KiB time=N/A bitrate=N/A speed=N/A
frame= 0 fps=0.0 q=0.0 size= 0KiB time=N/A bitrate=N/A speed=N/A
frame= 0 fps=0.0 q=0.0 size= 0KiB time=N/A bitrate=N/A speed=N/A
frame= 0 fps=0.0 q=0.0 size= 0KiB time=N/A bitrate=N/A speed=N/A
frame= 1 fps=0.1 q=0.0 size= 0KiB time=00:00:00.04 bitrate= 0.0kbits/s speed=0.00306x
frame= 1 fps=0.1 q=0.0 size= 0KiB time=00:00:00.04 bitrate= 0.0kbits/s speed=0.00295x
frame= 1 fps=0.1 q=0.0 size= 0KiB time=00:00:00.04 bitrate= 0.0kbits/s speed=0.00285x
frame= 1 fps=0.1 q=0.0 size= 0KiB time=00:00:00.04 bitrate= 0.0kbits/s speed=0.00275x
frame= 1 fps=0.1 q=0.0 size= 0KiB time=00:00:00.04 bitrate= 0.0kbits/s speed=0.00266x
frame= 1 fps=0.1 q=0.0 size= 0KiB time=00:00:00.04 bitrate= 0.0kbits/s speed=0.00258x
frame= 1 fps=0.1 q=0.0 size= 0KiB time=00:00:00.04 bitrate= 0.0kbits/s speed=0.0025x
frame= 1 fps=0.1 q=0.0 size= 0KiB time=00:00:00.04 bitrate= 0.0kbits/s speed=0.00243x
frame= 1 fps=0.1 q=0.0 size= 0KiB time=00:00:00.04 bitrate= 0.0kbits/s speed=0.00236x
frame= 1 fps=0.1 q=0.0 size= 0KiB time=00:00:00.04 bitrate= 0.0kbits/s speed=0.0023x
frame= 1 fps=0.1 q=0.0 size= 0KiB time=00:00:00.04 bitrate= 0.0kbits/s speed=0.00223x
frame= 1 fps=0.1 q=0.0 size= 0KiB time=00:00:00.04 bitrate= 0.0kbits/s speed=0.00217x
frame= 1 fps=0.1 q=0.0 size= 0KiB time=00:00:00.04 bitrate= 0.0kbits/s speed=0.00212x
frame= 1 fps=0.0 q=0.0 size= 0KiB time=00:00:00.04 bitrate= 0.0kbits/s speed=0.00207x
frame= 1 fps=0.0 q=0.0 size= 0KiB time=00:00:00.04 bitrate= 0.0kbits/s speed=0.00202x
frame= 1 fps=0.0 q=0.0 size= 0KiB time=00:00:00.04 bitrate= 0.0kbits/s speed=0.00197x
frame= 1 fps=0.0 q=0.0 size= 0KiB time=00:00:00.04 bitrate= 0.0kbits/s speed=0.00192x
frame= 1 fps=0.0 q=0.0 size= 0KiB time=00:00:00.04 bitrate= 0.0kbits/s speed=0.00188x
frame= 1 fps=0.0 q=0.0 size= 0KiB time=00:00:00.04 bitrate= 0.0kbits/s speed=0.00184x
frame= 1 fps=0.0 q=0.0 size= 0KiB time=00:00:00.04 bitrate= 0.0kbits/s speed=0.0018x
frame= 1 fps=0.0 q=0.0 size= 0KiB time=00:00:00.04 bitrate= 0.0kbits/s speed=0.00176x
frame= 1 fps=0.0 q=0.0 size= 0KiB time=00:00:00.04 bitrate= 0.0kbits/s speed=0.00172x
frame= 1 fps=0.0 q=0.0 size= 0KiB time=00:00:00.04 bitrate= 0.0kbits/s speed=0.00169x

Notes
- This is what I'm experimenting with to replace animated GIFs.
-
Calling an animated AVIF in a standard HTML
<img>
tag works on my mac in Firefox, Safari, and Chrome. Need to do more testing though to get a better idea of support. - I'm my older iPhone the animation gets pretty slow with bigger files. (the first test I did was ~1200 pixels wide at 30fpx. The speed it played back varied. The first bit was pretty much real time, then it slowed to probably 5fps or so) (TODO: Get iPhone model number)
- On my older iPad the animation only played one time then stopped on the first frame in Safari (TODO: get the version number)
- TODO: note about Can I Use support and Baseline 2024 inclusion and how that doesn't really talk about animated stuff, but maybe it's all baked in?
- TODO: Figure out if there are built in ways to click to start stop the animation. (There's nothing obvious in the right click menu for Zen)
- Make a process with a web component that allows you to stop/start the animation.
-- end of line --