Decode forgotten Pioneer car-stereo .lkd animations and watch them glow again — live in your browser or as a Linux desktop visualizer.
翻译准备中
正在加载完整 README。
查看完整 README ↗Old Pioneer head units (e.g. the DEH-P7600MP) let you upload custom animations
to their blue OEL display via CD or PC link, stored as .lkd files no modern
software could open. Carozerra decodes them and brings the look back — on the
web or on a Linux desktop, with the stereo's own controls doing real things.
.lkd turned out to be a thin wrapper around entirely standard formats —
no proprietary codec, no guesswork left in the pipeline:
offset bytes
0x00 "zLKD" magic (7A 4C 4B 44)
0x04 uint32 version = 3
0x08 uint32 (unknown) = 1
0x0C uint32 (unknown) = 7
0x10 uint32 frame count = 60
0x14 gzip stream ──▶ gunzip ──▶ TAR archive
└─ one member = a 24-bit Windows BMP
BMP = 256 × 3840, bottom-up, BGR
= 60 stacked frames of 256 × 64
Strip the 20-byte header → gunzip → tar → read the BMP → slice it into 60
frames of 256 × 64. Native palette is cyan-blue rgb(7,158,175) + white on
black — the classic blue-OEL glow — and artwork is dithered (mountains,
waterfalls, leaping dolphins, etc.).
Decodes fully client-side — DecompressionStream for gzip, an inline tar
reader, a BMP parser to canvas. 83 built-in clips (movies, backgrounds, stills,
level meters, and a full-color set — see assets/clips/) can be picked from
a gallery with category filters. Small posters load as they enter view; full
clips load when selected or intentionally previewed. Previews animate on hover
or keyboard focus, respecting reduced-motion preferences;
drag-and-drop (or click) still lets you load any other .lkd file — nothing is
uploaded anywhere. GIF and WebM export (with the retro phosphor glow baked into
the output) are available via the Export buttons.
Requires a browser with
DecompressionStream(current Chrome/Firefox/Edge).
←→ browse the gallery, and the footer's Changelog link opens
CHANGELOG.md in a modal — fetched at click time, so it never drifts from the
file in the repo.
To build and preview locally:
python3 packaging/build-web.py
python3 -m http.server -d dist/web 8000
Open http://localhost:8000. The build stages the player, faceplate, all clips,
and changelog into dist/web/. The faceplate is web/pioneer.webp, a
committed WebP copy of assets/pioneer.png; regenerate it if the PNG changes.
The live player is hosted on Cloudflare Pages at
carozerra.yousufkhan.uk.
The Cloudflare Pages project carozerra is connected to this GitHub repository:
production branch main, build command python3 packaging/build-web.py, and
output directory dist/web. Cloudflare manages the custom domain's DNS and
HTTPS certificate. Every push to main deploys through Cloudflare's native Git
integration; no deployment token or Node dependencies are needed.
The old GitHub Pages address stays online as a small browser redirect, preserving paths, query parameters, and fragments. Its no-JavaScript fallback redirects to the new homepage. GitHub Pages does not provide configurable HTTP redirects, so this is not an HTTP 301. The redirect is published only after the same commit is live on Cloudflare. The custom domain belongs to the Cloudflare Pages project; do not assign it to the GitHub Pages site.
The player advertises its new canonical URL, robots.txt, and sitemap.xml.
The existing Google Analytics measurement ID is unchanged. After migrating,
update the Analytics web stream URL and add/verify the new URL in Search
Console, then submit https://carozerra.yousufkhan.uk/sitemap.xml.
Adsterra placements are configured in web/ads.js: one banner below the player
(728×90 on viewports at least 808px wide, otherwise 320×50) and a native unit
below About. Each placement loads when it approaches the viewport. The banner
runs in its own iframe so the provider's atOptions global stays separate from
the player; crossing the desktop breakpoint replaces it with the other size.
The 300×250 unit is unused. Browser checks mock ad scripts, so they do not
generate live ad impressions. Verify actual delivery and impression reporting
on the production domain after deployment.
The web player uses a graphite and silver palette with locally hosted IBM Plex Sans. On phones, it opens with an enlarged animation view; View full stereo switches to the faceplate without restarting playback. Speed, glow, and frame scrubbing are under Playback settings, and Export offers GIF and WebM.
After changing bundled clips, regenerate the committed gallery posters with
python3 packaging/build-web-previews.py (requires Pillow). The fonts and their
license are in web/fonts/.
With the local server running, browser checks can be run with
python3 tests/web_player.py using Python's playwright package and Google
Chrome at /usr/bin/google-chrome. Set CAROZERRA_URL to test another local
server. Screenshots are written under .superpowers/implementation/.
A frameless, transparent, stereo-shaped window: the faceplate floats on your desktop and animations play on its OEL screen, with the stereo's own controls wired to real actions.
| Control | Action |
|---|---|
| Presets 1–6 | switch animation (first six clips) |
| Left knob | drag to rotate / scroll wheel → system volume |
| Right nav knob | left/right = prev/next clip · up/down = animation speed |
| FUNC (by the display) | toggle retro glow |
| ESC (top-right) | quit |
| drag body / edges | move / resize the window (aspect-locked) |
Keyboard: ←→ clip, ↑↓ speed, F glow, 1–6, F1 control map, Esc.
The control map above is also shown on the faceplate for a few seconds at
launch, and F1 brings it back. Esc closes it rather than quitting, so
dismissing the overlay can't take the app down with it.
以上为 README 的开头部分。其余内容请阅读原文。 查看完整 README ↗