v0.5.0: send album art to the Chromecast
The device is on a TV, so it should show the cover. play_media now carries thumb=, which pychromecast folds into metadata["images"] — the field the receiver paints full-screen. Verified against the real device: it fetches both the audio and the artwork URL from us on every track change. Album art lives in the audio file's tags rather than as a file of its own, so TrackServer tokens now resolve to an _Asset that is either a path or a blob held in memory. Audio and art get separate eviction rings so a cover can't push out the previous track's audio while the device is still fetching it; Range and HEAD work on both. The image type is sniffed from the cover's magic bytes rather than trusted from the tag — ID3 APIC mimes are routinely wrong or blank, and the receiver silently drops an image whose declared type doesn't match its content. Anything unrecognized is treated as "no cover". Best-effort throughout: no art, junk where the art should be, or an unreadable file all just play without a cover rather than failing the load. Also sends albumArtist and trackNumber in the metadata. tests/test_round29.py: 74 tests; 447 pass overall. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,24 @@
|
||||
## Done
|
||||
|
||||
### Round 30 (2026-08-13) — Album art on the cast device (v0.5.0)
|
||||
|
||||
The Chromecast is on a TV, so it should show the cover. `play_media` now
|
||||
carries `thumb=`, which pychromecast folds into `metadata["images"]` — the
|
||||
field the receiver paints full-screen. Verified against the real device: it
|
||||
fetches both the audio and the artwork URL from us on every track change.
|
||||
|
||||
- [x] **`TrackServer` serves in-memory blobs** — album art lives in the audio
|
||||
file's tags, not as a file of its own, so a token now resolves to an
|
||||
`_Asset` that is either a path or bytes. Audio and art get **separate
|
||||
eviction rings**, so a cover can't push out the previous track's audio while
|
||||
a device is still fetching it. Range and HEAD work on both.
|
||||
- [x] **`support.image_type_for`** sniffs the cover's type from its magic bytes
|
||||
rather than trusting the tag — ID3 APIC mimes are routinely wrong or blank,
|
||||
and the receiver silently drops an image whose type doesn't match.
|
||||
- [x] **Best-effort throughout** — no cover, junk where the cover should be, or
|
||||
an unreadable file all just play without art rather than failing the load.
|
||||
- [x] Also sends `albumArtist` and `trackNumber` in the metadata.
|
||||
|
||||
### Round 29 (2026-08-13) — Cast to Chromecast (v0.4.0)
|
||||
|
||||
The Device menu is now **Connections**, with "Connect to Chromecast…" alongside
|
||||
|
||||
Reference in New Issue
Block a user