Audio plays inside the card
Pronunciation audio plays inside the card instead of linking out.
Added
-
Embedded audio. Recordings are downloaded when the package is built and
shipped inside the.apkg, so the Pronunciation field is now
[sound:...]and plays in place. A link opened a browser, which is not
reviewing; embedded audio also works on AnkiDroid and AnkiMobile and keeps
working when the source is down.ADR-009 rejected this on size grounds and the estimate was wrong. Measured
on real Commons files — De-Haus 16 KB, De-Spaziergang 30 KB — a 240-card
German deck costs about 5 MB, not the "tens of megabytes" assumed.
Wikimedia already serves them as MP3, so nothing is converted. -
media.py, with an on-disk cache (MEDIA_DIR, defaultmedia/) so a word
met in a second video is not downloaded twice. -
A link fallback per card. When a download fails the card keeps the
linked URL rather than losing the audio entirely. This is routine, not
defensive padding: dictionaryapi.dev served one word's audio and returned
502 for another in the same minute. -
Paced downloads. Audio requests are spread across the run at
MEDIA_RATE_LIMITper second (default 1.25) after a burst of
MEDIA_BURST, and a429is retried for the period the server asks for.Without this the feature above barely worked.
upload.wikimedia.org
rate-limits per IP — about ten requests, then429withRetry-After: 11
— so an 8-worker pool drained the allowance in under a second. A real
406-card German run embedded 13 recordings and linked the other 364,
with no error and a valid package. Going sequential did not help; only
spacing the requests did. ARCHITECTURE.md 8.35. -
Progress output while audio downloads. Paced downloading of a few
hundred files takes minutes, and the CLI previously sat silent at
"Building Anki package...". The embedded-versus-linked count was already
being logged atINFO, below the defaultWARNINGlevel, so the one
number that revealed the bug above was written and discarded.
Fixed
- The documented non-interactive recipe crashed.
echo "s" | make run
supplies one line; the queued-word prompt consumed it and the import prompt
then hitEOFError, ending the run with a traceback after the package had
been written. All prompts now treat exhausted stdin as "no input" and take
a safe default. CLAUDE.md 4.4.
Known issues
- Images are ADR-009 phase 3 and deliberately not built: sampling
measured 2 of 5 usable, withlaufenreturning a coin from the town of
Laufen. They need a relevance gate before they are worth having.