Same-day re-cut on the per-day mutable CalVer scheme (post-v2026.06.04 papercut).
Notification / lock-screen art now matches the in-app album cover
On-device observation: the MediaController notification and lock-screen background showed a different album cover than the in-app surfaces for some tracks.
Root cause — two different art sources:
In-app covers come from TrackRef.coverUrl → /api/albums/{id}/cover (server album-level art).
The notification art came from the stream's embedded ID3/FLAC tags (MediaMetadata.artworkData), because PlayerController.toMediaItem never set artworkUri. Media3's BitmapLoader.loadBitmapFromMetadata prefers artworkData over artworkUri, and ExoPlayer extracts embedded picture frames into the live metadata. For tracks whose embedded tag art differs from the server album cover (compilations, re-grouped singles), the two surfaces disagreed.
Fix (3 files):
PlayerController.toMediaItem — set artworkUri to coverUrl. Verified against Media3 1.10.1 source: MediaMetadata.Builder.populate() overwrites artworkUri + artworkData as an atomic pair, and ExoPlayerImpl.buildUpdatedMediaMetadata layers MediaItem metadata over stream metadata — so the MediaItem URI clears the embedded artworkData. Album cover wins on both surfaces.
PlayerFactory.buildBitmapLoader — OkHttp-backed CacheBitmapLoader(DataSourceBitmapLoader(...)) so the authed placeholder.invalid cover URL resolves (Media3's default DefaultHttpDataSource loader can't rewrite the host or attach the auth cookie). CacheBitmapLoader dedupes refetches across metadata refreshes.
MinstrelPlayerService — attach via MediaSession.Builder.setBitmapLoader.
Net: notification, lock screen, BT/AVRCP, Auto, Pixel Watch all show the same album cover as the app regardless of file tags.
Verify on device
Play a track whose embedded tag art differs from its server album cover (a compilation or re-grouped single) → notification / lock-screen background now matches the in-app cover.
Same-day re-cut on the per-day mutable CalVer scheme (post-v2026.06.04 papercut).
## Notification / lock-screen art now matches the in-app album cover
On-device observation: the MediaController notification and lock-screen background showed a *different* album cover than the in-app surfaces for some tracks.
**Root cause — two different art sources:**
- In-app covers come from `TrackRef.coverUrl` → `/api/albums/{id}/cover` (server album-level art).
- The notification art came from the **stream's embedded ID3/FLAC tags** (`MediaMetadata.artworkData`), because `PlayerController.toMediaItem` never set `artworkUri`. Media3's `BitmapLoader.loadBitmapFromMetadata` prefers `artworkData` over `artworkUri`, and ExoPlayer extracts embedded picture frames into the live metadata. For tracks whose embedded tag art differs from the server album cover (compilations, re-grouped singles), the two surfaces disagreed.
**Fix (3 files):**
- `PlayerController.toMediaItem` — set `artworkUri` to `coverUrl`. Verified against Media3 1.10.1 source: `MediaMetadata.Builder.populate()` overwrites `artworkUri` + `artworkData` as an atomic pair, and `ExoPlayerImpl.buildUpdatedMediaMetadata` layers MediaItem metadata over stream metadata — so the MediaItem URI **clears** the embedded `artworkData`. Album cover wins on both surfaces.
- `PlayerFactory.buildBitmapLoader` — OkHttp-backed `CacheBitmapLoader(DataSourceBitmapLoader(...))` so the authed `placeholder.invalid` cover URL resolves (Media3's default `DefaultHttpDataSource` loader can't rewrite the host or attach the auth cookie). `CacheBitmapLoader` dedupes refetches across metadata refreshes.
- `MinstrelPlayerService` — attach via `MediaSession.Builder.setBitmapLoader`.
Net: notification, lock screen, BT/AVRCP, Auto, Pixel Watch all show the same album cover as the app regardless of file tags.
## Verify on device
- Play a track whose embedded tag art differs from its server album cover (a compilation or re-grouped single) → notification / lock-screen background now matches the in-app cover.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
The MediaController notification / lock-screen background pulled artwork
from the stream's embedded ID3/FLAC tags (artworkData) because the
MediaItem never set artworkUri — a different source than the in-app
album cover (/api/albums/{id}/cover). For tracks whose embedded tag art
differs from the server album cover, the two surfaces disagreed.
- PlayerController.toMediaItem: set artworkUri to TrackRef.coverUrl.
MediaMetadata.populate() overwrites artworkUri+artworkData as a pair,
so the MediaItem URI clears the embedded bytes ExoPlayer extracts from
the stream — the album cover now wins on both surfaces.
- PlayerFactory.buildBitmapLoader: OkHttp-backed CacheBitmapLoader so the
authed placeholder cover URL resolves (the default DefaultHttpDataSource
loader can't rewrite placeholder.invalid or attach the auth cookie).
- MinstrelPlayerService: attach it via MediaSession.setBitmapLoader.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Same-day re-cut on the per-day mutable CalVer scheme (post-v2026.06.04 papercut).
Notification / lock-screen art now matches the in-app album cover
On-device observation: the MediaController notification and lock-screen background showed a different album cover than the in-app surfaces for some tracks.
Root cause — two different art sources:
TrackRef.coverUrl→/api/albums/{id}/cover(server album-level art).MediaMetadata.artworkData), becausePlayerController.toMediaItemnever setartworkUri. Media3'sBitmapLoader.loadBitmapFromMetadataprefersartworkDataoverartworkUri, and ExoPlayer extracts embedded picture frames into the live metadata. For tracks whose embedded tag art differs from the server album cover (compilations, re-grouped singles), the two surfaces disagreed.Fix (3 files):
PlayerController.toMediaItem— setartworkUritocoverUrl. Verified against Media3 1.10.1 source:MediaMetadata.Builder.populate()overwritesartworkUri+artworkDataas an atomic pair, andExoPlayerImpl.buildUpdatedMediaMetadatalayers MediaItem metadata over stream metadata — so the MediaItem URI clears the embeddedartworkData. Album cover wins on both surfaces.PlayerFactory.buildBitmapLoader— OkHttp-backedCacheBitmapLoader(DataSourceBitmapLoader(...))so the authedplaceholder.invalidcover URL resolves (Media3's defaultDefaultHttpDataSourceloader can't rewrite the host or attach the auth cookie).CacheBitmapLoaderdedupes refetches across metadata refreshes.MinstrelPlayerService— attach viaMediaSession.Builder.setBitmapLoader.Net: notification, lock screen, BT/AVRCP, Auto, Pixel Watch all show the same album cover as the app regardless of file tags.
Verify on device
🤖 Generated with Claude Code
The MediaController notification / lock-screen background pulled artwork from the stream's embedded ID3/FLAC tags (artworkData) because the MediaItem never set artworkUri — a different source than the in-app album cover (/api/albums/{id}/cover). For tracks whose embedded tag art differs from the server album cover, the two surfaces disagreed. - PlayerController.toMediaItem: set artworkUri to TrackRef.coverUrl. MediaMetadata.populate() overwrites artworkUri+artworkData as a pair, so the MediaItem URI clears the embedded bytes ExoPlayer extracts from the stream — the album cover now wins on both surfaces. - PlayerFactory.buildBitmapLoader: OkHttp-backed CacheBitmapLoader so the authed placeholder cover URL resolves (the default DefaultHttpDataSource loader can't rewrite placeholder.invalid or attach the auth cookie). - MinstrelPlayerService: attach it via MediaSession.setBitmapLoader. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>