Debug qobuz pas encore parfait mais mieux
This commit is contained in:
@@ -127,13 +127,16 @@ impl SourcesExt for Server {
|
||||
|
||||
tracing::info!("Initializing Qobuz source...");
|
||||
|
||||
// Obtenir l'URL de base du serveur
|
||||
let base_url = self.base_url();
|
||||
|
||||
// Créer le client depuis la config
|
||||
let client = QobuzClient::from_config()
|
||||
.await
|
||||
.map_err(|e| SourceInitError::QobuzError(format!("Failed to create client: {}", e)))?;
|
||||
|
||||
// Créer la source depuis le registry
|
||||
let source = QobuzSource::from_registry(client)
|
||||
let source = QobuzSource::from_registry(client, base_url)
|
||||
.map_err(|e| SourceInitError::QobuzError(format!("Failed to create source: {}", e)))?;
|
||||
|
||||
// Enregistrer la source
|
||||
@@ -154,13 +157,16 @@ impl SourcesExt for Server {
|
||||
|
||||
tracing::info!("Initializing Qobuz source with explicit credentials...");
|
||||
|
||||
// Obtenir l'URL de base du serveur
|
||||
let base_url = self.base_url();
|
||||
|
||||
// Créer le client avec credentials
|
||||
let client = QobuzClient::new(username, password)
|
||||
.await
|
||||
.map_err(|e| SourceInitError::QobuzError(format!("Failed to authenticate: {}", e)))?;
|
||||
|
||||
// Créer la source depuis le registry
|
||||
let source = QobuzSource::from_registry(client)
|
||||
let source = QobuzSource::from_registry(client, base_url)
|
||||
.map_err(|e| SourceInitError::QobuzError(format!("Failed to create source: {}", e)))?;
|
||||
|
||||
// Enregistrer la source
|
||||
|
||||
@@ -26,6 +26,9 @@ pub struct QobuzCredentials {
|
||||
pub username: Option<String>,
|
||||
/// Mot de passe Qobuz (optionnel, lu depuis la config si absent)
|
||||
pub password: Option<String>,
|
||||
/// URL de base du serveur (optionnelle, "http://localhost:8080" par défaut)
|
||||
#[serde(default)]
|
||||
pub base_url: Option<String>,
|
||||
}
|
||||
|
||||
/// Paramètres pour Radio Paradise
|
||||
@@ -75,6 +78,11 @@ async fn register_qobuz(Json(creds): Json<QobuzCredentials>) -> impl IntoRespons
|
||||
use pmoqobuz::{QobuzClient, QobuzSource};
|
||||
use pmosource::api::register_source;
|
||||
|
||||
// Utiliser l'URL de base depuis les params ou une valeur par défaut
|
||||
let base_url = creds
|
||||
.base_url
|
||||
.unwrap_or_else(|| "http://localhost:8080".to_string());
|
||||
|
||||
// Créer le client selon les credentials fournis
|
||||
let client_result = if let (Some(username), Some(password)) = (creds.username, creds.password) {
|
||||
QobuzClient::new(&username, &password).await
|
||||
@@ -96,7 +104,7 @@ async fn register_qobuz(Json(creds): Json<QobuzCredentials>) -> impl IntoRespons
|
||||
};
|
||||
|
||||
// Créer et enregistrer la source depuis le registry
|
||||
let source = match QobuzSource::from_registry(client) {
|
||||
let source = match QobuzSource::from_registry(client, base_url) {
|
||||
Ok(s) => Arc::new(s),
|
||||
Err(e) => {
|
||||
return (
|
||||
|
||||
@@ -124,7 +124,7 @@
|
||||
//! let cover_cache = Arc::new(CoverCache::new("./cache/covers", 500)?);
|
||||
//! let audio_cache = Arc::new(AudioCache::new("./cache/audio", 100)?);
|
||||
//!
|
||||
//! let source = QobuzSource::new(client, cover_cache, audio_cache);
|
||||
//! let source = QobuzSource::new(client, cover_cache, audio_cache, "http://localhost:8080");
|
||||
//! # Ok(())
|
||||
//! # }
|
||||
//! ```
|
||||
@@ -145,7 +145,7 @@
|
||||
//! let cover_cache = Arc::new(CoverCache::new("./cache/covers", 500)?);
|
||||
//! let audio_cache = Arc::new(AudioCache::new("./cache/audio", 100)?);
|
||||
//!
|
||||
//! let source = QobuzSource::new(client, cover_cache, audio_cache);
|
||||
//! let source = QobuzSource::new(client, cover_cache, audio_cache, "http://localhost:8080");
|
||||
//!
|
||||
//! // Add a track with caching
|
||||
//! let tracks = source.client().get_favorite_tracks().await?;
|
||||
|
||||
@@ -56,7 +56,7 @@ const DEFAULT_IMAGE: &[u8] = include_bytes!("../assets/default.webp");
|
||||
/// let client = QobuzClient::from_config().await?;
|
||||
/// let cover_cache = Arc::new(cover_cache::new_cache("/tmp/qobuz_covers", 256)?);
|
||||
/// let audio_cache = Arc::new(audio_cache::new_cache("/tmp/qobuz_audio", 64)?);
|
||||
/// let source = QobuzSource::new(client, cover_cache, audio_cache);
|
||||
/// let source = QobuzSource::new(client, cover_cache, audio_cache, "http://localhost:8080");
|
||||
///
|
||||
/// println!("Source: {}", source.name());
|
||||
/// println!("Supports FIFO: {}", source.supports_fifo());
|
||||
@@ -80,6 +80,9 @@ struct QobuzSourceInner {
|
||||
/// Cache manager (centralisé)
|
||||
cache_manager: SourceCacheManager,
|
||||
|
||||
/// Base URL for streaming server (e.g., "http://192.168.0.138:8080")
|
||||
base_url: String,
|
||||
|
||||
/// Update tracking
|
||||
update_counter: tokio::sync::RwLock<u32>,
|
||||
last_change: tokio::sync::RwLock<SystemTime>,
|
||||
@@ -100,12 +103,13 @@ impl QobuzSource {
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `client` - Authenticated Qobuz API client
|
||||
/// * `base_url` - Base URL for streaming server (e.g., "http://192.168.0.138:8080")
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the caches are not initialized in the registry
|
||||
#[cfg(feature = "server")]
|
||||
pub fn from_registry(client: QobuzClient) -> Result<Self> {
|
||||
pub fn from_registry(client: QobuzClient, base_url: impl Into<String>) -> Result<Self> {
|
||||
let cache_manager = SourceCacheManager::from_registry("qobuz".to_string())?;
|
||||
let client = Arc::new(client);
|
||||
cache_manager.register_lazy_provider(Arc::new(QobuzLazyProvider::new(client.clone())));
|
||||
@@ -114,6 +118,7 @@ impl QobuzSource {
|
||||
inner: Arc::new(QobuzSourceInner {
|
||||
client,
|
||||
cache_manager,
|
||||
base_url: base_url.into(),
|
||||
update_counter: tokio::sync::RwLock::new(0),
|
||||
last_change: tokio::sync::RwLock::new(SystemTime::now()),
|
||||
}),
|
||||
@@ -127,10 +132,12 @@ impl QobuzSource {
|
||||
/// * `client` - Authenticated Qobuz API client
|
||||
/// * `cover_cache` - Cover image cache (required)
|
||||
/// * `audio_cache` - Audio cache (required)
|
||||
/// * `base_url` - Base URL for streaming server (e.g., "http://192.168.0.138:8080")
|
||||
pub fn new(
|
||||
client: QobuzClient,
|
||||
cover_cache: Arc<CoverCache>,
|
||||
audio_cache: Arc<AudioCache>,
|
||||
base_url: impl Into<String>,
|
||||
) -> Self {
|
||||
let cache_manager = SourceCacheManager::new("qobuz".to_string(), cover_cache, audio_cache);
|
||||
let client = Arc::new(client);
|
||||
@@ -140,6 +147,7 @@ impl QobuzSource {
|
||||
inner: Arc::new(QobuzSourceInner {
|
||||
client,
|
||||
cache_manager,
|
||||
base_url: base_url.into(),
|
||||
update_counter: tokio::sync::RwLock::new(0),
|
||||
last_change: tokio::sync::RwLock::new(SystemTime::now()),
|
||||
}),
|
||||
@@ -578,6 +586,15 @@ impl QobuzSource {
|
||||
} else {
|
||||
warn!("No qobuz_track_id metadata for {}", pk);
|
||||
}
|
||||
|
||||
// Convertir URL relative en URL absolue
|
||||
// From: /audio/flac/QOBUZ:123
|
||||
// To: http://192.168.0.138:8080/audio/flac/QOBUZ:123
|
||||
if let Some(resource) = item.resources.first_mut() {
|
||||
if resource.url.starts_with('/') {
|
||||
resource.url = format!("{}{}", self.inner.base_url, resource.url);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
item.parent_id = parent_id.clone();
|
||||
|
||||
@@ -217,6 +217,29 @@ impl SourceCacheManager {
|
||||
}
|
||||
}
|
||||
|
||||
/// Obtenir l'URL absolue d'un fichier audio en cache à partir de son pk
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `pk` - Clé primaire du fichier audio dans le cache
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// L'URL absolue complète du fichier audio (ex: http://localhost:8080/audio/flac/QOBUZ:123)
|
||||
pub fn audio_url(&self, _pk: &str) -> Result<String> {
|
||||
#[cfg(feature = "server")]
|
||||
{
|
||||
pmoupnp::cache_registry::build_audio_url(_pk, None)
|
||||
.map_err(|e| MusicSourceError::CacheError(e.to_string()))
|
||||
}
|
||||
#[cfg(not(feature = "server"))]
|
||||
{
|
||||
Err(MusicSourceError::CacheError(
|
||||
"Server feature not enabled - cannot build audio URL".to_string(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
/// Cacher une piste audio depuis une URL
|
||||
///
|
||||
/// Utilise la collection de cette source pour organiser les pistes.
|
||||
|
||||
Reference in New Issue
Block a user