Correction de la source radio paradise pour avoir un sous dossier par canal

This commit is contained in:
2025-10-19 18:14:28 +02:00
parent 455fc4ed21
commit a809fca1ac
6 changed files with 748 additions and 448 deletions

2
Cargo.lock generated
View File

@@ -2479,6 +2479,7 @@ dependencies = [
"axum", "axum",
"bytes", "bytes",
"claxon", "claxon",
"flacenc",
"futures", "futures",
"hound", "hound",
"pmoaudiocache", "pmoaudiocache",
@@ -2491,6 +2492,7 @@ dependencies = [
"reqwest", "reqwest",
"serde", "serde",
"serde_json", "serde_json",
"symphonia",
"tempfile", "tempfile",
"thiserror 1.0.69", "thiserror 1.0.69",
"tokio", "tokio",

View File

@@ -90,9 +90,7 @@ impl CacheInput {
pub async fn bytes(&mut self) -> Result<Bytes, String> { pub async fn bytes(&mut self) -> Result<Bytes, String> {
match &mut self.inner { match &mut self.inner {
CacheInputInner::Http { CacheInputInner::Http {
response, response, buffer, ..
buffer,
..
} => { } => {
if let Some(bytes) = buffer.clone() { if let Some(bytes) = buffer.clone() {
return Ok(bytes); return Ok(bytes);
@@ -130,9 +128,7 @@ impl CacheInput {
pub fn into_byte_stream(self) -> ByteStream { pub fn into_byte_stream(self) -> ByteStream {
match self.inner { match self.inner {
CacheInputInner::Http { CacheInputInner::Http {
response, response, buffer, ..
buffer,
..
} => { } => {
if let Some(response) = response { if let Some(response) = response {
Box::pin( Box::pin(

View File

@@ -27,6 +27,7 @@ anyhow = "1.0"
# Streaming de bytes # Streaming de bytes
bytes = "1.5" bytes = "1.5"
futures = "0.3" futures = "0.3"
flacenc = "0.4"
# Logging # Logging
tracing = "0.1" tracing = "0.1"
@@ -34,6 +35,9 @@ tracing = "0.1"
# URL manipulation # URL manipulation
url = "2.5" url = "2.5"
# Audio decoding/encoding
symphonia = { version = "0.5", features = ["all"] }
# Per-track feature dependencies # Per-track feature dependencies
claxon = { version = "0.4", optional = true } claxon = { version = "0.4", optional = true }
hound = { version = "3.5", optional = true } hound = { version = "3.5", optional = true }

View File

@@ -92,6 +92,19 @@ impl RadioParadiseClient {
self.channel self.channel
} }
fn block_base_for_channel(channel: u8) -> String {
format!("https://apps.radioparadise.com/blocks/chan/{}", channel)
}
/// Clone the client with a different channel while preserving other settings.
pub fn clone_with_channel(&self, channel: u8) -> Self {
let mut cloned = self.clone();
cloned.channel = channel;
cloned.block_base = Self::block_base_for_channel(channel);
cloned.next_block_url = None;
cloned
}
/// Get a block by event ID /// Get a block by event ID
/// ///
/// If `event` is None, returns the current block. /// If `event` is None, returns the current block.
@@ -123,7 +136,8 @@ impl RadioParadiseClient {
url.query_pairs_mut() url.query_pairs_mut()
.append_pair("bitrate", &self.bitrate.as_u8().to_string()) .append_pair("bitrate", &self.bitrate.as_u8().to_string())
.append_pair("info", "true"); .append_pair("info", "true")
.append_pair("channel", &self.channel.to_string());
if let Some(event_id) = event { if let Some(event_id) = event {
url.query_pairs_mut() url.query_pairs_mut()
@@ -348,10 +362,16 @@ impl ClientBuilder {
builder.build()? builder.build()?
}; };
let block_base = if self.block_base == DEFAULT_BLOCK_BASE {
RadioParadiseClient::block_base_for_channel(self.channel)
} else {
self.block_base.clone()
};
Ok(RadioParadiseClient { Ok(RadioParadiseClient {
client, client,
api_base: self.api_base, api_base: self.api_base,
block_base: self.block_base, block_base,
image_base: self.image_base, image_base: self.image_base,
bitrate: self.bitrate, bitrate: self.bitrate,
channel: self.channel, channel: self.channel,

File diff suppressed because it is too large Load Diff

View File

@@ -23,6 +23,7 @@ use pmoaudiocache::{AudioMetadata, Cache as AudioCache};
use pmocovers::Cache as CoverCache; use pmocovers::Cache as CoverCache;
use std::collections::HashMap; use std::collections::HashMap;
use std::sync::Arc; use std::sync::Arc;
use tokio::io::AsyncRead;
use tokio::sync::RwLock; use tokio::sync::RwLock;
/// Métadonnées d'une piste en cache /// Métadonnées d'une piste en cache
@@ -216,6 +217,32 @@ impl SourceCacheManager {
Ok(pk) Ok(pk)
} }
/// Cache un flux audio via un reader asynchrone
pub async fn cache_audio_from_reader<R>(
&self,
source_uri: &str,
reader: R,
length: Option<u64>,
) -> Result<String>
where
R: AsyncRead + Send + Unpin + 'static,
{
let pk = self
.audio_cache
.add_from_reader(source_uri, reader, length, Some(&self.collection_id))
.await
.map_err(|e| MusicSourceError::CacheError(e.to_string()))?;
Ok(pk)
}
/// Attend que le fichier audio correspondant soit complètement disponible
pub async fn wait_audio_ready(&self, pk: &str) -> Result<()> {
self.audio_cache
.wait_until_finished(pk)
.await
.map_err(|e| MusicSourceError::CacheError(e.to_string()))
}
/// Mettre à jour les métadonnées d'une piste /// Mettre à jour les métadonnées d'une piste
/// ///
/// Enregistre ou met à jour les métadonnées de cache pour une piste. /// Enregistre ou met à jour les métadonnées de cache pour une piste.