Downloads & cache
The two-cache model, lazy URL resolution, expiry handling, and download states.
Downloading and streaming share one pipeline but two separate stores, which is why the Storage screen can clear them independently.
Two caches
| Cache | Holds | Cleared by |
|---|---|---|
playerCache | Whatever streamed through the player | Player Cache |
downloadCache | Tracks explicitly downloaded | Downloaded Cache |
Only playerCache is subject to the Limit Player Cache ceiling (100 MB – 8 GB, or
unlimited). Downloads are never evicted by that limit — otherwise "downloaded for offline"
would not survive a long listening session.
Lazy URL resolution
Downloads go through a ResolvingDataSource wrapping a CacheDataSource. For each request:
Check both caches. If the range is already cached, the request is served locally and no network call happens.
Otherwise resolve a fresh stream URL through StreamRepository.
If a stored format still has a URL and hasn't expired, reuse it — but verify it doesn't return 403 first.
On expiry or 403, fetch a new stream URL and retry with it.
That 403 check matters: YouTube stream URLs are time-limited and tied to a session, so a URL cached yesterday will often still look valid while returning 403 on use.
Video downloads
Video and audio arrive as separate streams. Media IDs are prefixed (MERGING_DATA_TYPE.VIDEO)
so the resolver knows which stream to fetch, and the two are merged into one file.
Download states
DownloadState has four values, not three:
| Constant | Value | Meaning |
|---|---|---|
STATE_NOT_DOWNLOADED | 0 | Nothing stored |
STATE_PREPARING | 1 | Queued, resolving before bytes move |
STATE_DOWNLOADING | 2 | Transfer in progress |
STATE_DOWNLOADED | 3 | Complete |
The preparing state is the one users notice as "nothing is happening yet" — it covers URL resolution before any bytes are transferred.
