◆ FFmpeg で MP4 動画などから簡単にアニメーション AVIF に変換できる

Edge で AVIF が使えるようになって 1 ヶ月以上経ちましたし AVIF を使うところを増やしていこうかなと思ってます

Animated AVIF

AVIF って静止画だけじゃなくて GIF みたいにアニメーションも対応してるそうです
JPG の代わりだけじゃなくて GIF の代わりにも使えそうですね

どうやって作るんだろうと思ったのですが とりあえず FFmpeg を見てみたら対応してました

ffmpeg -i video.mp4 img.avif

こんな感じです
こだわりがないなら特別なオプションはいらないです
お手軽ですね

古い方法

ググると出てくる方法だと 一度中間形式みたいなファイルを作る面倒そうな方法が出てきます
FFmpeg からファイルを出力して それを avifenc コマンドに入れて AVIF 化します
avifenc コマンドは libavif のリポジトリからダウンロードできる公式のものです
https://github.com/AOMediaCodec/libavif

今だと上に書いたような FFmpeg だけでできるので簡単です
古い FFmpeg だと対応してなくて↓みたいなエラーになります

Unable to find a suitable output format for 'img.avif'

エラーになる場合は新しい FFmpeg に更新すると使えるようになります
https://github.com/BtbN/FFmpeg-Builds/releases

私が使ったのは n6.1 の gpl 版です
この辺は詳しくないのですが README の説明を見る限り gpl が全部入りで良さそうです
サイズ的にも一番大きいですし

gpl/lgpl では lgpl だと GPL-only のライブラリが入っていなくて libx264 や libx265 が使えないようです
x264/x265 って MP4 などの動画では結構使われると思うのでこれがないと不便そうです
shared は libav* などが共有ライブラリに置き換えられるようです
Linux で共有ライブラリが入ってるならこれで良さそうですが Windows だと dll ファイルを別途持ってこないとになるので shared でないほうが良さそうです
libav* というとワイルドカード的に libavif も含まれそうですが 昔からある libav を指してるようにも思うので libavif を使う上で必要なのかはわかってません

試しに MP4 から変換してみた AVIF ファイルです





画質や滑らかさは十分だと思います
回転する方でフレームレートが低めなのは元が画面キャプチャで MP4 からこれくらいです

サービス側の対応

ブラウザが対応してもサービス側での対応ってまだまだなんですよね
アップロードするときに画像として認識されず使えないことが多いです

例えばこのライブドアブログもそうです
ライブドアブログの場合は任意のフォーマットで自由にファイルを置ける場所があるのでそこに配置はできるのですが JPG や PNG みたいな通常の画像と同じように扱えず不便です
また 自由に置ける場所に置いても Content-Type が image/avif にならず text/plain になるので img タグを通さないと文字化けしたテキストで表示されてしまいます

ブログのような場所なら ほぼ 1 回限りで使い回さないので HTML 中に Data URI として埋め込んでしまうなんて方法でもいいのかもしれません

<!doctype html>
<img src="data:image/avif;base64,AAAAIGZ0eXBhdmlmAAAAAGF2aWZtaWYxbWlhZk1BMUIAAAE7bWV0YQAAAAAAAAAhaGRscgAAAAAAAAAAcGljdAAAAAAAAAAAAAAAAAAAAAAOcGl0bQAAAAAAAQAAACxpbG9jAAAAAEQAAAIAAQAAAAEAAAI/AAAB/gACAAAAAQAAAWMAAADcAAAAQWlpbmYAAAAAAAIAAAAaaW5mZQIAAAAAAQAAYXYwMUNvbG9yAAAAABlpbmZlAgAAAQACAABFeGlmRXhpZgAAAAAaaXJlZgAAAAAAAAAOY2RzYwACAAEAAQAAAHlpcHJwAAAAWWlwY28AAAAUaXNwZQAAAAAAAABQAAAAKAAAABBwYXNwAAAAAQAAAAEAAAAMYXYxQ4EAHAAAAAAOcGl4aQAAAAABCAAAABNjb2xybmNseAABAA0AAYAAAAAYaXBtYQAAAAAAAAABAAEFAQKDhIUAAALibWRhdAAAAABJSSoACAAAAAYAEgEDAAEAAAABAAAAGgEFAAEAAABWAAAAGwEFAAEAAABeAAAAKAEDAAEAAAACAAAAMQECABEAAABmAAAAaYcEAAEAAAB4AAAAAAAAAGAAAAABAAAAYAAAAAEAAABwYWludC5uZXQgNS4wLjEyAAAFAACQBwAEAAAAMDIzMAGgAwABAAAAAQAAAAKgBAABAAAAUAAAAAOgBAABAAAAKAAAAAWgBAABAAAAugAAAAAAAAACAAEAAgAEAAAAUjk4AAIABwAEAAAAMDEwMAAAAAASAAoJGBlnz8sBDQGgMu4DEYAEQXjZLyxufVSq9eMugtmtVBYoBwFb6uuIIzuXH8sirgDpkXb4dxFAq0jqmnU9OPyfO0tiV54UFCtL7Ok+/K6mx7YxT3+XM1xfdMRXHebgop1wrmHAqa0oRnNaHi9MbGdsXMKHAmaKiiKblHxskICQtOgkhpr8B1CQmY9VPJLh5R0AZcXMJ3xWfqzbwm0jOj2t9sHAtEBseQYfTQTHSHVRpeAyJjjAOfGlKArm9mgUkohx+hNXhF2f5ssD7C/YYXFu2qzROuS4hc2BCvTFdFRcMlkL3m/EmmL1q+H5/f/Cl/mOJ2wdHS2+RwVGTXOKJly2wXpuXT1cMcnxqQsAqtITaxkM5RDYquanqVmxauTw/UcniQBrRR22vKesMNa8BXDIyVvTNeWqSsUKeYPulddlugouK8PphlP46mb2+Va/wn9FVCAtm6hpBZzaKbFjYdlIcD1C7PJXV6oreXf7ziricZliUZLDT+oyuR76csNywjPp6aKtoI7DkjkTsn7gxBEYr7SJXqlPYTXqbIv/t8lexKaHJ2vs7rq3wVgKzsarbP9QRk1pRBUmLX0aoTJgPcQTXkZmfFIfvO5RcPa9C1ITrqBS3gmILn/Qria1TTsvJsMwvo4Kj6PCAoJ698mlh4tao7m/Brjlt5gDjTA=">

みたいな感じです
ただ img タグがかなり長くなると本文中にそれだけで場所を取って見づらいので データはページ内の別の場所に置いておいて JavaScript で読み込ませるほうがいいのかもです

<!doctype html>

<script type="module">
const init = () => {
for (const elem of document.querySelectorAll("img[data-ref]")) {
const id = elem.dataset.ref
const data_elem = document.getElementById(id)
if (!data_elem) return
elem.src = `data:${data_elem.type},${data_elem.textContent}`
}
}
init()
</script>

<script type="image/avif;base64" id="avif-image1">
AAAAIGZ0eXBhdmlmAAAAAGF2aWZtaWYxbWlhZk1BMUIAAAE7bWV0YQAAAAAAAAAh
aGRscgAAAAAAAAAAcGljdAAAAAAAAAAAAAAAAAAAAAAOcGl0bQAAAAAAAQAAACxp
bG9jAAAAAEQAAAIAAQAAAAEAAAI/AAAB/gACAAAAAQAAAWMAAADcAAAAQWlpbmYA
AAAAAAIAAAAaaW5mZQIAAAAAAQAAYXYwMUNvbG9yAAAAABlpbmZlAgAAAQACAABF
eGlmRXhpZgAAAAAaaXJlZgAAAAAAAAAOY2RzYwACAAEAAQAAAHlpcHJwAAAAWWlw
Y28AAAAUaXNwZQAAAAAAAABQAAAAKAAAABBwYXNwAAAAAQAAAAEAAAAMYXYxQ4EA
HAAAAAAOcGl4aQAAAAABCAAAABNjb2xybmNseAABAA0AAYAAAAAYaXBtYQAAAAAA
AAABAAEFAQKDhIUAAALibWRhdAAAAABJSSoACAAAAAYAEgEDAAEAAAABAAAAGgEF
AAEAAABWAAAAGwEFAAEAAABeAAAAKAEDAAEAAAACAAAAMQECABEAAABmAAAAaYcE
AAEAAAB4AAAAAAAAAGAAAAABAAAAYAAAAAEAAABwYWludC5uZXQgNS4wLjEyAAAF
AACQBwAEAAAAMDIzMAGgAwABAAAAAQAAAAKgBAABAAAAUAAAAAOgBAABAAAAKAAA
AAWgBAABAAAAugAAAAAAAAACAAEAAgAEAAAAUjk4AAIABwAEAAAAMDEwMAAAAAAS
AAoJGBlnz8sBDQGgMu4DEYAEQXjZLyxufVSq9eMugtmtVBYoBwFb6uuIIzuXH8si
rgDpkXb4dxFAq0jqmnU9OPyfO0tiV54UFCtL7Ok+/K6mx7YxT3+XM1xfdMRXHebg
op1wrmHAqa0oRnNaHi9MbGdsXMKHAmaKiiKblHxskICQtOgkhpr8B1CQmY9VPJLh
5R0AZcXMJ3xWfqzbwm0jOj2t9sHAtEBseQYfTQTHSHVRpeAyJjjAOfGlKArm9mgU
kohx+hNXhF2f5ssD7C/YYXFu2qzROuS4hc2BCvTFdFRcMlkL3m/EmmL1q+H5/f/C
l/mOJ2wdHS2+RwVGTXOKJly2wXpuXT1cMcnxqQsAqtITaxkM5RDYquanqVmxauTw
/UcniQBrRR22vKesMNa8BXDIyVvTNeWqSsUKeYPulddlugouK8PphlP46mb2+Va/
wn9FVCAtm6hpBZzaKbFjYdlIcD1C7PJXV6oreXf7ziricZliUZLDT+oyuR76csNy
wjPp6aKtoI7DkjkTsn7gxBEYr7SJXqlPYTXqbIv/t8lexKaHJ2vs7rq3wVgKzsar
bP9QRk1pRBUmLX0aoTJgPcQTXkZmfFIfvO5RcPa9C1ITrqBS3gmILn/Qria1TTsv
JsMwvo4Kj6PCAoJ698mlh4tao7m/Brjlt5gDjTA=
</script>

<img data-ref="avif-image1">

話がそれてきましたが AVIF は WebP と合わせて普及が進んでほしいですね
もう JPG と GIF は新規ファイルには使わないくらいにしたいです