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...");
|
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
|
// Créer le client depuis la config
|
||||||
let client = QobuzClient::from_config()
|
let client = QobuzClient::from_config()
|
||||||
.await
|
.await
|
||||||
.map_err(|e| SourceInitError::QobuzError(format!("Failed to create client: {}", e)))?;
|
.map_err(|e| SourceInitError::QobuzError(format!("Failed to create client: {}", e)))?;
|
||||||
|
|
||||||
// Créer la source depuis le registry
|
// 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)))?;
|
.map_err(|e| SourceInitError::QobuzError(format!("Failed to create source: {}", e)))?;
|
||||||
|
|
||||||
// Enregistrer la source
|
// Enregistrer la source
|
||||||
@@ -154,13 +157,16 @@ impl SourcesExt for Server {
|
|||||||
|
|
||||||
tracing::info!("Initializing Qobuz source with explicit credentials...");
|
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
|
// Créer le client avec credentials
|
||||||
let client = QobuzClient::new(username, password)
|
let client = QobuzClient::new(username, password)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| SourceInitError::QobuzError(format!("Failed to authenticate: {}", e)))?;
|
.map_err(|e| SourceInitError::QobuzError(format!("Failed to authenticate: {}", e)))?;
|
||||||
|
|
||||||
// Créer la source depuis le registry
|
// 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)))?;
|
.map_err(|e| SourceInitError::QobuzError(format!("Failed to create source: {}", e)))?;
|
||||||
|
|
||||||
// Enregistrer la source
|
// Enregistrer la source
|
||||||
|
|||||||
@@ -26,6 +26,9 @@ pub struct QobuzCredentials {
|
|||||||
pub username: Option<String>,
|
pub username: Option<String>,
|
||||||
/// Mot de passe Qobuz (optionnel, lu depuis la config si absent)
|
/// Mot de passe Qobuz (optionnel, lu depuis la config si absent)
|
||||||
pub password: Option<String>,
|
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
|
/// Paramètres pour Radio Paradise
|
||||||
@@ -75,6 +78,11 @@ async fn register_qobuz(Json(creds): Json<QobuzCredentials>) -> impl IntoRespons
|
|||||||
use pmoqobuz::{QobuzClient, QobuzSource};
|
use pmoqobuz::{QobuzClient, QobuzSource};
|
||||||
use pmosource::api::register_source;
|
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
|
// Créer le client selon les credentials fournis
|
||||||
let client_result = if let (Some(username), Some(password)) = (creds.username, creds.password) {
|
let client_result = if let (Some(username), Some(password)) = (creds.username, creds.password) {
|
||||||
QobuzClient::new(&username, &password).await
|
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
|
// 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),
|
Ok(s) => Arc::new(s),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -124,7 +124,7 @@
|
|||||||
//! let cover_cache = Arc::new(CoverCache::new("./cache/covers", 500)?);
|
//! let cover_cache = Arc::new(CoverCache::new("./cache/covers", 500)?);
|
||||||
//! let audio_cache = Arc::new(AudioCache::new("./cache/audio", 100)?);
|
//! 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(())
|
//! # Ok(())
|
||||||
//! # }
|
//! # }
|
||||||
//! ```
|
//! ```
|
||||||
@@ -145,7 +145,7 @@
|
|||||||
//! let cover_cache = Arc::new(CoverCache::new("./cache/covers", 500)?);
|
//! let cover_cache = Arc::new(CoverCache::new("./cache/covers", 500)?);
|
||||||
//! let audio_cache = Arc::new(AudioCache::new("./cache/audio", 100)?);
|
//! 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
|
//! // Add a track with caching
|
||||||
//! let tracks = source.client().get_favorite_tracks().await?;
|
//! 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 client = QobuzClient::from_config().await?;
|
||||||
/// let cover_cache = Arc::new(cover_cache::new_cache("/tmp/qobuz_covers", 256)?);
|
/// 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 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!("Source: {}", source.name());
|
||||||
/// println!("Supports FIFO: {}", source.supports_fifo());
|
/// println!("Supports FIFO: {}", source.supports_fifo());
|
||||||
@@ -80,6 +80,9 @@ struct QobuzSourceInner {
|
|||||||
/// Cache manager (centralisé)
|
/// Cache manager (centralisé)
|
||||||
cache_manager: SourceCacheManager,
|
cache_manager: SourceCacheManager,
|
||||||
|
|
||||||
|
/// Base URL for streaming server (e.g., "http://192.168.0.138:8080")
|
||||||
|
base_url: String,
|
||||||
|
|
||||||
/// Update tracking
|
/// Update tracking
|
||||||
update_counter: tokio::sync::RwLock<u32>,
|
update_counter: tokio::sync::RwLock<u32>,
|
||||||
last_change: tokio::sync::RwLock<SystemTime>,
|
last_change: tokio::sync::RwLock<SystemTime>,
|
||||||
@@ -100,12 +103,13 @@ impl QobuzSource {
|
|||||||
/// # Arguments
|
/// # Arguments
|
||||||
///
|
///
|
||||||
/// * `client` - Authenticated Qobuz API client
|
/// * `client` - Authenticated Qobuz API client
|
||||||
|
/// * `base_url` - Base URL for streaming server (e.g., "http://192.168.0.138:8080")
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
///
|
///
|
||||||
/// Returns an error if the caches are not initialized in the registry
|
/// Returns an error if the caches are not initialized in the registry
|
||||||
#[cfg(feature = "server")]
|
#[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 cache_manager = SourceCacheManager::from_registry("qobuz".to_string())?;
|
||||||
let client = Arc::new(client);
|
let client = Arc::new(client);
|
||||||
cache_manager.register_lazy_provider(Arc::new(QobuzLazyProvider::new(client.clone())));
|
cache_manager.register_lazy_provider(Arc::new(QobuzLazyProvider::new(client.clone())));
|
||||||
@@ -114,6 +118,7 @@ impl QobuzSource {
|
|||||||
inner: Arc::new(QobuzSourceInner {
|
inner: Arc::new(QobuzSourceInner {
|
||||||
client,
|
client,
|
||||||
cache_manager,
|
cache_manager,
|
||||||
|
base_url: base_url.into(),
|
||||||
update_counter: tokio::sync::RwLock::new(0),
|
update_counter: tokio::sync::RwLock::new(0),
|
||||||
last_change: tokio::sync::RwLock::new(SystemTime::now()),
|
last_change: tokio::sync::RwLock::new(SystemTime::now()),
|
||||||
}),
|
}),
|
||||||
@@ -127,10 +132,12 @@ impl QobuzSource {
|
|||||||
/// * `client` - Authenticated Qobuz API client
|
/// * `client` - Authenticated Qobuz API client
|
||||||
/// * `cover_cache` - Cover image cache (required)
|
/// * `cover_cache` - Cover image cache (required)
|
||||||
/// * `audio_cache` - Audio 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(
|
pub fn new(
|
||||||
client: QobuzClient,
|
client: QobuzClient,
|
||||||
cover_cache: Arc<CoverCache>,
|
cover_cache: Arc<CoverCache>,
|
||||||
audio_cache: Arc<AudioCache>,
|
audio_cache: Arc<AudioCache>,
|
||||||
|
base_url: impl Into<String>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let cache_manager = SourceCacheManager::new("qobuz".to_string(), cover_cache, audio_cache);
|
let cache_manager = SourceCacheManager::new("qobuz".to_string(), cover_cache, audio_cache);
|
||||||
let client = Arc::new(client);
|
let client = Arc::new(client);
|
||||||
@@ -140,6 +147,7 @@ impl QobuzSource {
|
|||||||
inner: Arc::new(QobuzSourceInner {
|
inner: Arc::new(QobuzSourceInner {
|
||||||
client,
|
client,
|
||||||
cache_manager,
|
cache_manager,
|
||||||
|
base_url: base_url.into(),
|
||||||
update_counter: tokio::sync::RwLock::new(0),
|
update_counter: tokio::sync::RwLock::new(0),
|
||||||
last_change: tokio::sync::RwLock::new(SystemTime::now()),
|
last_change: tokio::sync::RwLock::new(SystemTime::now()),
|
||||||
}),
|
}),
|
||||||
@@ -578,6 +586,15 @@ impl QobuzSource {
|
|||||||
} else {
|
} else {
|
||||||
warn!("No qobuz_track_id metadata for {}", pk);
|
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();
|
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
|
/// Cacher une piste audio depuis une URL
|
||||||
///
|
///
|
||||||
/// Utilise la collection de cette source pour organiser les pistes.
|
/// Utilise la collection de cette source pour organiser les pistes.
|
||||||
|
|||||||
Reference in New Issue
Block a user