diff --git a/jamendody/src/api.rs b/jamendody/src/api.rs index 995f8c2..5933acd 100644 --- a/jamendody/src/api.rs +++ b/jamendody/src/api.rs @@ -260,22 +260,26 @@ impl Jam for JamApi { } async fn track_stream(&self, id: &str) -> Result { - let dtos: Vec = self - .get( - "tracks", - &[ - ("id", id.to_string()), - ("audioformat", self.audioformat.clone()), - ], - ) - .await?; - let audio = dtos - .into_iter() - .next() - .and_then(|t| t.audio) - .filter(|u| !u.is_empty()) - .ok_or(FetchError::NotStreamable)?; - Ok(audio) + // Try the configured format first, then fall back to Jamendo's native + // default (mp31): some formats — notably mp32 — return an empty `audio` + // URL for many tracks, and an empty stream must degrade to the freely + // streamable one rather than skip the track. + let mut attempts: Vec> = vec![vec![ + ("id", id.to_string()), + ("audioformat", self.audioformat.clone()), + ]]; + if !self.audioformat.is_empty() { + attempts.push(vec![("id", id.to_string())]); + } + for query in &attempts { + let dtos: Vec = self.get("tracks", query).await?; + if let Some(audio) = dtos.into_iter().next().and_then(|t| t.audio) { + if !audio.is_empty() { + return Ok(audio); + } + } + } + Err(FetchError::NotStreamable) } } diff --git a/jamendody/src/lib.rs b/jamendody/src/lib.rs index 27c6981..4069ec6 100644 --- a/jamendody/src/lib.rs +++ b/jamendody/src/lib.rs @@ -42,8 +42,11 @@ pub const DEFAULT_SEARCH_RESULTS: usize = 50; pub const DEFAULT_ALBUM_TRACKS: usize = 200; /// Default per-request timeout in seconds. pub const DEFAULT_CALL_TIMEOUT_SECS: u64 = 30; -/// Default requested audio format (`mp32` = higher-bitrate MP3). -pub const DEFAULT_AUDIOFORMAT: &str = "mp32"; +/// Default requested audio streaming format. `mp31` is Jamendo's freely +/// streamable MP3; `mp32` (higher bitrate) is *not* reliably provisioned for the +/// streaming `audio` URL and comes back empty for many tracks, so it is a poor +/// default (a Pro account can still set it explicitly). +pub const DEFAULT_AUDIOFORMAT: &str = "mp31"; /// Provider settings, persisted as `jamendo.toml`. `client_id` is **required**: /// without it the provider does not mount (D5). The rest have defaults.