perf(cast): cache-first resolver + offline tier + cheap quality (P1+P2)
The cast was slow because the resolver always did a full CMAF download (~10s for a 190MB hi-res FLAC) and never read the cache — unlike the fast last Tauri build, which resolved bytes cache-first. - P1 cache-first: Player::fetch_for_external_stream now checks L1 (in-memory) -> L2 (on-disk playback cache) before any download. The gapless prefetch already warms the next 2 tracks at UltraHiRes while casting, so next/advance/replay are now instant; only a cold track pays the download. - Offline tier: CoreBridge::fetch_for_external_stream_resolved gains offline + sink params and tries resolve_offline_bytes (local CMAF decrypt, no network) before the network path — a downloaded track casts fast with no connection (the same local-segments+decrypt path offline playback uses). Replaces the hard "Qobuz cast needs a connection" gate (offline-cached tracks now work). - P2 quality label: derived from the track's catalog metadata (bit_depth/sample_rate/hires) in cast_track — no extra API call, consistent whether bytes came from cache, offline, or network. cargo check -p qbz-slint: clean. cc
This commit is contained in:
3 files changed
+108
-48
No files matched your search
@@ -3765,22 +3765,54 @@ impl Player {
|
||||
|
||||
/// Resolve a fully-materialized audio asset for an EXTERNAL renderer
|
||||
/// (Chromecast / DLNA), carrying the bytes verbatim plus the MIME and the
|
||||
/// quality that was ACTUALLY delivered. Used by the Cast path through the
|
||||
/// local media server.
|
||||
/// quality. Used by the Cast path through the local media server.
|
||||
///
|
||||
/// Unlike `fetch_for_gapless`, this deliberately does NOT read the local
|
||||
/// playback cache: those bytes were fetched at the user's *local* quality
|
||||
/// setting, whereas casting attempts the best tier (UltraHiRes-first) and
|
||||
/// must report the real delivered quality. The CMAF path is preferred (it
|
||||
/// yields decrypted FLAC and exposes the resolved sample-rate/bit-depth);
|
||||
/// the legacy stream-URL download is the fallback.
|
||||
/// Cache-first (P1, matches the fast Tauri cast path + consumes the gapless
|
||||
/// prefetch): L1 in-memory -> L2 on-disk playback cache (both decrypted
|
||||
/// FLAC) -> network. A prefetched/replayed track is served instantly; only a
|
||||
/// cold track pays the CMAF download. On a cache hit the delivered quality is
|
||||
/// not known here (no metadata stored with the bytes) — the caller derives
|
||||
/// the quality label from the track's catalog metadata; the network path
|
||||
/// returns the precise resolved tier.
|
||||
pub async fn fetch_for_external_stream(
|
||||
&self,
|
||||
client: &QobuzClient,
|
||||
track_id: u64,
|
||||
quality: Quality,
|
||||
) -> Option<ExternalStreamAsset> {
|
||||
// Preferred: CMAF full download (Akamai CDN) -> decrypted FLAC.
|
||||
// L1: in-memory cache (warmed by the gapless prefetch / a prior play).
|
||||
if let Some(cached) = self.audio_cache.get(track_id) {
|
||||
log::info!(
|
||||
"[CAST-FETCH] Track {track_id} from MEMORY cache ({} bytes)",
|
||||
cached.size_bytes
|
||||
);
|
||||
return Some(ExternalStreamAsset {
|
||||
bytes: cached.data,
|
||||
content_type: "audio/flac".to_string(),
|
||||
quality: StreamQualityInfo::from_raw(0, None, None),
|
||||
duration_secs: None,
|
||||
origin: AssetOrigin::Cache,
|
||||
});
|
||||
}
|
||||
// L2: on-disk plain-FLAC playback cache; warm L1 on the way out.
|
||||
if let Some(playback_cache) = self.audio_cache.get_playback_cache() {
|
||||
if let Some(audio_data) = playback_cache.get(track_id) {
|
||||
log::info!(
|
||||
"[CAST-FETCH] Track {track_id} from DISK cache ({} bytes)",
|
||||
audio_data.len()
|
||||
);
|
||||
self.audio_cache.insert(track_id, audio_data.clone());
|
||||
return Some(ExternalStreamAsset {
|
||||
bytes: audio_data,
|
||||
content_type: "audio/flac".to_string(),
|
||||
quality: StreamQualityInfo::from_raw(0, None, None),
|
||||
duration_secs: None,
|
||||
origin: AssetOrigin::Cache,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Cold: CMAF full download (Akamai CDN) -> decrypted FLAC.
|
||||
match qbz_qobuz::cmaf::download_full_with_quality(client, track_id, quality).await {
|
||||
Ok((bytes, q)) => {
|
||||
log::info!(
|
||||
|
||||
Reference in new issue
Block a user