Skip to content

docs(hero): 4x sped-up README hero GIF - #217

Merged
juacker merged 1 commit into
mainfrom
hero-gif-4x
Sep 20, 2026
Merged

juacker merged 1 commit into
mainfrom
hero-gif-4x

Conversation

@juacker

@juacker juacker commented Sep 20, 2026

Copy link
Copy Markdown
Collaborator

Replaces docs/clai-hero.gif (the README hero) with a 4× sped-up re-encode of the 115 s landing capture. No README change: the path is unchanged.

before after
duration 16.0 s 28.75 s
size 2.69 MB 3.34 MB
resolution 860×484 640×340
fps 10 12
loop infinite infinite (NETSCAPE2.0, loop_count=0)

Why the filter chain looks like this

The source capture is variable frame rate — measured PTS gaps range from 0.033 s to 0.446 s (~20.7 fps average). setpts=PTS/4 alone works on presentation timestamps and does not normalise variable timing, so the chain resamples to CFR first, then scales PTS:

ffmpeg -y -i video-landing.mp4 \
  -vf "fps=30,scale=640:-2:flags=lanczos,setpts=PTS/4,fps=12,split[s0][s1];\
[s0]palettegen=stats_mode=full[p];[s1][p]paletteuse=dither=sierra2_4a" \
  -loop 0 docs/clai-hero.gif

Deviation: 640 px wide at 12 fps, not 720 px at 15 fps

720/15 came out at 4.92 MB — under the 5 MB ceiling but far from the ≤3 MB ideal and ~83% heavier than the asset it replaces. Measured fallback ladder (width → fps → dither, as specified):

variant size
720 × 15, sierra2_4a 4.92 MB
720 × 15, bayer_scale=5 4.73 MB
720 × 15, 128-colour palette 4.36 MB
720 × 12, sierra2_4a 4.25 MB
640 × 15, sierra2_4a 3.89 MB
640 × 12, sierra2_4a 3.34 MB ← chosen
640 × 10, sierra2_4a 3.29 MB

Bayer dithering barely helped on this content (dense UI text), so it was not used. 640×12 is the smallest variant that stays recognisable: dropping to 10 fps saves only 0.05 MB and makes the already-4×-fast motion visibly choppy, so 12 fps is the stopping point. The GIF is rendered at width="100%" in the README, so the narrower intrinsic width costs no layout change.

Verification

  • 345 frames, 28.75 s, 640×340 (even dimensions), infinite loop confirmed by parsing the NETSCAPE2.0 application extension (loop_count=0) and the 0x3B trailer.
  • Temporal mapping is 4×: source t=80 s matches GIF t=20 s at mean |diff| 0.52/255 (palette dither noise only).
  • Full decode is clean; the GIF covers the whole flow from the first to the last frame of the source.

Re-encode of the 115 s source capture at 4x speed (28.7 s), 640x340 at
12 fps with a full-stats palette, 3.3 MB.

The source is variable frame rate (PTS gaps 0.033-0.446 s), so the chain
normalises to CFR before scaling PTS: fps=30,scale,setpts=PTS/4,fps=12.
@juacker
juacker marked this pull request as ready for review September 20, 2026 21:23
@juacker
juacker merged commit 72687b1 into main Sep 20, 2026
2 checks passed
@juacker
juacker deleted the hero-gif-4x branch September 20, 2026 21:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant