diff --git a/src-tauri/src/cast/dlna/commands.rs b/src-tauri/src/cast/dlna/commands.rs
index 0c3fa2333..244b276a1 100644
--- a/src-tauri/src/cast/dlna/commands.rs
+++ b/src-tauri/src/cast/dlna/commands.rs
@@ -152,11 +152,14 @@ pub async fn dlna_play_track(
url.ok_or_else(|| "Failed to build media URL".to_string())?
};
+ log::info!("DLNA: Playing track {} via MediaServer URL: {}", track_id, url);
+ log::debug!("DLNA: Content-Type from Qobuz: {}", content_type);
+
// Load media on DLNA device
{
let mut connection = dlna_state.connection.lock().await;
let conn = connection.as_mut().ok_or_else(|| "Not connected".to_string())?;
- conn.load_media(&url, &metadata).await.map_err(|e| e.to_string())?;
+ conn.load_media(&url, &metadata, &content_type).await.map_err(|e| e.to_string())?;
}
// Start playback
diff --git a/src-tauri/src/cast/dlna/device.rs b/src-tauri/src/cast/dlna/device.rs
index d8e56f45f..f53a71c41 100644
--- a/src-tauri/src/cast/dlna/device.rs
+++ b/src-tauri/src/cast/dlna/device.rs
@@ -101,7 +101,7 @@ impl DlnaConnection {
}
/// Set the media URI and start playback
- pub async fn load_media(&mut self, uri: &str, metadata: &DlnaMetadata) -> Result<(), DlnaError> {
+ pub async fn load_media(&mut self, uri: &str, metadata: &DlnaMetadata, content_type: &str) -> Result<(), DlnaError> {
if !self.connected {
return Err(DlnaError::NotConnected);
}
@@ -109,8 +109,12 @@ impl DlnaConnection {
let av_service = self.av_transport_service.as_ref()
.ok_or_else(|| DlnaError::Playback("Device has no AVTransport service".to_string()))?;
- // Build DIDL-Lite metadata
- let didl_metadata = build_didl_metadata(uri, metadata);
+ // Build DIDL-Lite metadata with actual content type
+ let didl_metadata = build_didl_metadata(uri, metadata, content_type);
+
+ log::debug!("DLNA: Loading media URI: {}", uri);
+ log::debug!("DLNA: Content-Type: {}", content_type);
+ log::debug!("DLNA: DIDL Metadata:\n{}", didl_metadata);
let payload = format!(
"0{}{}",
@@ -118,11 +122,15 @@ impl DlnaConnection {
xml_escape(&didl_metadata)
);
- av_service
+ let response = av_service
.action(&self.device_url, "SetAVTransportURI", &payload)
.await
- .map_err(|e| DlnaError::Playback(e.to_string()))?;
+ .map_err(|e| {
+ log::error!("DLNA: SetAVTransportURI failed: {}", e);
+ DlnaError::Playback(e.to_string())
+ })?;
+ log::debug!("DLNA: SetAVTransportURI response: {:?}", response);
self.current_uri = Some(uri.to_string());
log::info!("DLNA: Set URI to {}", uri);
@@ -138,13 +146,17 @@ impl DlnaConnection {
let av_service = self.av_transport_service.as_ref()
.ok_or_else(|| DlnaError::Playback("Device has no AVTransport service".to_string()))?;
- av_service
+ let response = av_service
.action(&self.device_url, "Play", "01")
.await
- .map_err(|e| DlnaError::Playback(e.to_string()))?;
+ .map_err(|e| {
+ log::error!("DLNA: Play action failed: {}", e);
+ DlnaError::Playback(e.to_string())
+ })?;
+ log::debug!("DLNA: Play response: {:?}", response);
self.is_playing = true;
- log::info!("DLNA: Play");
+ log::info!("DLNA: Play started successfully");
Ok(())
}
@@ -244,7 +256,7 @@ impl DlnaConnection {
}
/// Build DIDL-Lite metadata for a track
-fn build_didl_metadata(uri: &str, metadata: &DlnaMetadata) -> String {
+fn build_didl_metadata(uri: &str, metadata: &DlnaMetadata, content_type: &str) -> String {
let duration = metadata.duration_secs.map(|d| {
let hours = d / 3600;
let minutes = (d % 3600) / 60;
@@ -256,6 +268,10 @@ fn build_didl_metadata(uri: &str, metadata: &DlnaMetadata) -> String {
.map(|url| format!(r#"{}"#, xml_escape(url)))
.unwrap_or_default();
+ // Use actual content type for protocolInfo - critical for DLNA compatibility
+ // Many devices reject content if protocolInfo doesn't match actual MIME type
+ let protocol_info = format!("http-get:*:{}:*", content_type);
+
format!(
r#"
-
@@ -264,7 +280,7 @@ fn build_didl_metadata(uri: &str, metadata: &DlnaMetadata) -> String {
{}
{}
{}
- {}
+ {}
object.item.audioItem.musicTrack
"#,
@@ -274,6 +290,7 @@ fn build_didl_metadata(uri: &str, metadata: &DlnaMetadata) -> String {
xml_escape(&metadata.artist),
artwork,
duration,
+ protocol_info,
xml_escape(uri)
)
}