🎞️

MP4からアニメーションAPNG・WebPを作る方法と動作確認

に公開

「動画(mp4)をサクッと動く画像にしたい!」というときの実用メモです。
ここでは ffmpeg だけで APNG と アニメーション WebP を作り、ちゃんと動くか確認するところまで手を動かします。
(macOS / Apple Silicon 前提。Linux/Windows でもコマンドはほぼ同じです)

0. 準備

インストール(Homebrew)

brew install ffmpeg
# 追加チェック系(任意)
brew install imagemagick   # identify でフレーム数やループ可否を確認

サンプル動画(input.mp4)を用意して、作業ディレクトリに置いておきます。
今回は実験として BigBuckBunnyの一番サイズが小さいもの を利用しました。また、以降は BigBuckBunny_320x180.mp4 をリネームした input.mp4 を利用します。

1. まずは“素材を整える”:切り出し・縮小・fps 調整

アニメ画像は解像度とフレームレートでサイズが激変します。
先に好みの長さ・大きさ・fps に揃えておくのがコツ。

% ffmpeg -y -ss 0 -t 5 -i input.mp4 \                       
  -vf "fps=12,scale=512:-1:flags=lanczos" \
  -an -c:v libx264 -preset veryfast -crf 18 \
  trimmed.mp4
ffmpeg version 7.1.1 Copyright (c) 2000-2025 the FFmpeg developers
  built with Apple clang version 17.0.0 (clang-1700.0.13.3)
  configuration: --prefix=/opt/homebrew/Cellar/ffmpeg/7.1.1_4 --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 'input.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: mp41
    creation_time   : 1970-01-01T00:00:00.000000Z
    title           : Big Buck Bunny
    artist          : Blender Foundation
    composer        : Blender Foundation
    date            : 2008
    encoder         : Lavf52.14.0
  Duration: 00:09:56.46, start: 0.000000, bitrate: 867 kb/s
  Stream #0:0[0x1](und): Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p(progressive), 320x180 [SAR 1:1 DAR 16:9], 702 kb/s, 24 fps, 24 tbr, 24 tbn (default)
      Metadata:
        creation_time   : 1970-01-01T00:00:00.000000Z
        handler_name    : VideoHandler
        vendor_id       : [0][0][0][0]
  Stream #0:1[0x2](und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 159 kb/s (default)
      Metadata:
        creation_time   : 1970-01-01T00:00:00.000000Z
        handler_name    : SoundHandler
        vendor_id       : [0][0][0][0]
Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
Press [q] to stop, [?] for help
[libx264 @ 0x146707a60] using SAR=1/1
[libx264 @ 0x146707a60] using cpu capabilities: ARMv8 NEON
[libx264 @ 0x146707a60] profile High, level 2.1, 4:2:0, 8-bit
[libx264 @ 0x146707a60] 264 - core 164 r3108 31e19f9 - H.264/MPEG-4 AVC codec - Copyleft 2003-2023 - http://www.videolan.org/x264.html - options: cabac=1 ref=1 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=2 psy=1 psy_rd=1.00:0.00 mixed_ref=0 me_range=16 chroma_me=1 trellis=0 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=0 threads=9 lookahead_threads=2 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=1 keyint=250 keyint_min=12 scenecut=40 intra_refresh=0 rc_lookahead=10 rc=crf mbtree=1 crf=18.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00
Output #0, mp4, to 'trimmed.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: mp41
    date            : 2008
    title           : Big Buck Bunny
    artist          : Blender Foundation
    composer        : Blender Foundation
    encoder         : Lavf61.7.100
  Stream #0:0(und): Video: h264 (avc1 / 0x31637661), yuv420p(tv, progressive), 512x288 [SAR 1:1 DAR 16:9], q=2-31, 12 fps, 12288 tbn (default)
      Metadata:
        creation_time   : 1970-01-01T00:00:00.000000Z
        handler_name    : VideoHandler
        vendor_id       : [0][0][0][0]
        encoder         : Lavc61.19.101 libx264
      Side data:
        cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: N/A
[out#0/mp4 @ 0x60000078c000] video:188KiB audio:0KiB subtitle:0KiB other streams:0KiB global headers:0KiB muxing overhead: 0.874187%
frame=   60 fps=0.0 q=-1.0 Lsize=     189KiB time=00:00:04.83 bitrate= 321.1kbits/s speed= 115x    
[libx264 @ 0x146707a60] frame I:2     Avg QP: 4.71  size:   853
[libx264 @ 0x146707a60] frame P:22    Avg QP:11.86  size:  5220
[libx264 @ 0x146707a60] frame B:36    Avg QP:14.71  size:  2085
[libx264 @ 0x146707a60] consecutive B-frames: 11.7% 16.7% 25.0% 46.7%
[libx264 @ 0x146707a60] mb I  I16..4: 95.2%  3.0%  1.8%
[libx264 @ 0x146707a60] mb P  I16..4: 38.0% 11.9%  6.4%  P16..4: 20.7% 11.6%  7.7%  0.0%  0.0%    skip: 3.7%
[libx264 @ 0x146707a60] mb B  I16..4: 11.8%  6.2%  1.8%  B16..8: 21.1% 10.1%  1.1%  direct:21.0%  skip:27.0%  L0:45.7% L1:41.5% BI:12.8%
[libx264 @ 0x146707a60] 8x8 transform intra:22.7% inter:28.1%
[libx264 @ 0x146707a60] coded y,uvDC,uvAC intra: 25.2% 45.7% 33.1% inter: 19.5% 41.6% 6.6%
[libx264 @ 0x146707a60] i16 v,h,dc,p: 71% 19%  8%  2%
[libx264 @ 0x146707a60] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 21% 32% 33%  1%  4%  2%  2%  1%  3%
[libx264 @ 0x146707a60] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 25% 30% 28%  1%  7%  3%  4%  1%  2%
[libx264 @ 0x146707a60] i8c dc,h,v,p: 65% 19% 12%  3%
[libx264 @ 0x146707a60] Weighted P-Frames: Y:50.0% UV:36.4%
[libx264 @ 0x146707a60] kb/s:306.57

ポイント

  • -ss/-t … 切り出し開始/長さ
  • fps=12 … アニメ用なら 8〜15fps が軽くて見栄えも良いことが多い
  • scale=512:-1 … 幅だけ指定(縦は自動)
  • -an … 音声は不要なので落とす

この trimmed.mp4 を APNG / WebP の共通ソースにします。

2. APNG を作る

% ffmpeg -y -i trimmed.mp4 -f apng -plays 0 out.apng
ffmpeg version 7.1.1 Copyright (c) 2000-2025 the FFmpeg developers
  built with Apple clang version 17.0.0 (clang-1700.0.13.3)
  configuration: --prefix=/opt/homebrew/Cellar/ffmpeg/7.1.1_4 --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 'trimmed.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    title           : Big Buck Bunny
    artist          : Blender Foundation
    composer        : Blender Foundation
    date            : 2008
    encoder         : Lavf61.7.100
  Duration: 00:00:05.00, start: 0.000000, bitrate: 310 kb/s
  Stream #0:0[0x1](und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(progressive), 512x288 [SAR 1:1 DAR 16:9], 307 kb/s, 12 fps, 12 tbr, 12288 tbn (default)
      Metadata:
        handler_name    : VideoHandler
        vendor_id       : [0][0][0][0]
        encoder         : Lavc61.19.101 libx264
Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> apng (native))
Press [q] to stop, [?] for help
[swscaler @ 0x138318000] [swscaler @ 0x160008000] No accelerated colorspace conversion found from yuv420p to rgb24.
[swscaler @ 0x138318000] [swscaler @ 0x160018000] No accelerated colorspace conversion found from yuv420p to rgb24.
[swscaler @ 0x138318000] [swscaler @ 0x160028000] No accelerated colorspace conversion found from yuv420p to rgb24.
[swscaler @ 0x138318000] [swscaler @ 0x160038000] No accelerated colorspace conversion found from yuv420p to rgb24.
[swscaler @ 0x138318000] [swscaler @ 0x160048000] No accelerated colorspace conversion found from yuv420p to rgb24.
[swscaler @ 0x138318000] [swscaler @ 0x160058000] No accelerated colorspace conversion found from yuv420p to rgb24.
[swscaler @ 0x138318000] [swscaler @ 0x160068000] No accelerated colorspace conversion found from yuv420p to rgb24.
[swscaler @ 0x138318000] [swscaler @ 0x160078000] No accelerated colorspace conversion found from yuv420p to rgb24.
[swscaler @ 0x138318000] [swscaler @ 0x160088000] No accelerated colorspace conversion found from yuv420p to rgb24.
[swscaler @ 0x138318000] [swscaler @ 0x160098000] No accelerated colorspace conversion found from yuv420p to rgb24.
[swscaler @ 0x138318000] [swscaler @ 0x1600a8000] No accelerated colorspace conversion found from yuv420p to rgb24.
Output #0, apng, to 'out.apng':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    title           : Big Buck Bunny
    artist          : Blender Foundation
    composer        : Blender Foundation
    date            : 2008
    encoder         : Lavf61.7.100
  Stream #0:0(und): Video: apng, rgb24(pc, gbr/unknown/unknown, progressive), 512x288 [SAR 1:1 DAR 16:9], q=2-31, 200 kb/s, 12 fps, 12 tbn (default)
      Metadata:
        handler_name    : VideoHandler
        vendor_id       : [0][0][0][0]
        encoder         : Lavc61.19.101 apng
[out#0/apng @ 0x60000177c000] video:4895KiB audio:0KiB subtitle:0KiB other streams:0KiB global headers:0KiB muxing overhead: 0.001716%
frame=   60 fps= 54 q=-0.0 Lsize=    4895KiB time=00:00:05.00 bitrate=8020.1kbits/s speed=4.54x

補足オプション

  • 透過を使う場合は元動画からアルファが必要ですが、通常の mp4 には無いので非透過で OK
  • Chrome / Safari / Firefox いずれも APNG を <img> でアニメ再生できます

3. アニメーション WebP を作る

ffmpeg -y -i trimmed.mp4 \
  -c:v libwebp -lossless 0 -quality 80 -compression_level 6 \
  -loop 0 out.webp

調整の目安

  • -quality 80 … 60〜85 あたりで微調整(大きくすると綺麗・重くなる)
  • -lossless 1 … ロスレス。画質は最高だがサイズは大きめ
  • -loop 0 … 無限ループ

4. 「高画質/小さめ」版の作り方

# 高画質APNG(サイズ重め)
ffmpeg -y -i trimmed.mp4 -f apng -plays 0 out_high.apng

# 小さめWebP(画質控えめ)
ffmpeg -y -i trimmed.mp4 -c:v libwebp -quality 65 -compression_level 6 -loop 0 out_small.webp

5. “動くか”を確認する

A. ブラウザで確認(最確実)

test.html を置いて開くだけ👇

<!doctype html>
<meta charset="utf-8">
<title>APNG / WebP 動作確認</title>
<style>
  body { font-family: system-ui, sans-serif; line-height: 1.6; padding: 24px; }
  figure { display: inline-block; margin: 0 24px 24px 0; }
  img { width: 320px; height: auto; border: 1px solid #ddd; border-radius: 8px; }
  figcaption { text-align: center; margin-top: 8px; color: #666; }
</style>

<h1>APNG / WebP 動作確認</h1>

<figure>
  <img src="out.apng" alt="APNG sample">
  <figcaption>APNG</figcaption>
</figure>

<figure>
  <img src="out.webp" alt="Animated WebP sample">
  <figcaption>Animated WebP</figcaption>
</figure>


<figure>
  <img src="out_high.apng" alt="APNG sample (high)">
  <figcaption>APNG sample (high)</figcaption>
</figure>

<figure>
  <img src="out_small.webp" alt="Animated WebP sample (small)">
  <figcaption>Animated WebP (small)</figcaption>
</figure>

動画ではありませんが、ブラウザを利用すると下記のような形で動くアニメーションを確認することができます。

alt text

B. 画像情報で確認(任意・CLI)

# コーデック確認
% ffprobe -v error -select_streams v:0 -show_entries stream=codec_name \
  -of default=nw=1:nk=1 out.webp
[webp @ 0x1496070d0] image data not found
webp
# フレーム数など(ImageMagick)
% magick identify -format "%f: %n frames, %Wx%H\n" out.apng out.webp

out.apng: 1 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288
out.webp: 60 frames, 512x288

まとめ

  • ffmpeg だけで MP4 → APNG / Animated WebP は簡単!
  • fps / 解像度 / quality の三点を抑えれば容量と見栄えの両立ができる
  • HTML の <img> に貼るだけで主要ブラウザでアニメ再生

楽しい“動く画像”ライフを! 🌀

Discussion