From 5d2f88aa9886153ae9651335f3a9219b00e33d6c Mon Sep 17 00:00:00 2001 From: Test User Date: Mon, 20 Jul 2026 15:29:54 +0200 Subject: [PATCH] Fix decoder panic on streamed network tracks Playing a network track panicked in rodio 0.22's symphonia backend: "Seek errors should not occur during initialization". During init symphonia probes the container length; on a source with no known byte length it seeks from the end, and StreamDownload handles that in a way rodio turns into an `unreachable!`. This surfaced after the dependency bump from rodio 0.17 (with the old custom SymphoniaDecoder) to 0.22. Pass the stream's content length to the decoder via with_byte_len (the local-file path already did this), which lets symphonia skip the end-relative seek entirely. Verified against a real Tidal AAC/mp4 stream: the streamed decode now succeeds instead of panicking. Co-Authored-By: Claude Fable 5 --- audio-player/src/player_engine.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/audio-player/src/player_engine.rs b/audio-player/src/player_engine.rs index 0cf3d79..113c6de 100644 --- a/audio-player/src/player_engine.rs +++ b/audio-player/src/player_engine.rs @@ -208,7 +208,15 @@ impl PlayerEngine { .map_err(|_| anyhow!("timed out opening stream after {STREAM_OPEN_TIMEOUT:?}"))? .context("failed to open http stream") })?; + // Symphonia probes the container length during init; without a + // known byte length it seeks from the end, which rodio 0.22 turns + // into an `unreachable!` panic on a streamed source. Handing it the + // content length up front avoids that seek entirely. + let byte_len = reader.content_length(); let mut builder = Decoder::builder().with_data(reader).with_seekable(true); + if let Some(len) = byte_len { + builder = builder.with_byte_len(len); + } if let Some(extension) = Path::new(url.path()).extension().and_then(|e| e.to_str()) { builder = builder.with_hint(extension);