use bytes::Bytes;
use url::Url;
use crate::Client;
use crate::data::TranscodeDecision;
use crate::error::Error;
impl Client {
pub async fn get_transcode_decision(
&self,
id: &str,
max_bit_rate: Option<i32>,
format: Option<&str>,
client_info: Option<&crate::data::ClientInfo>,
) -> Result<TranscodeDecision, Error> {
let mut params = vec![("id", id.to_string())];
if let Some(br) = max_bit_rate {
params.push(("maxBitRate", br.to_string()));
}
if let Some(f) = format {
params.push(("format", f.to_string()));
}
if let Some(info) = client_info {
let param_refs: Vec<(&str, &str)> =
params.iter().map(|(k, v)| (*k, v.as_str())).collect();
let url = self.build_url("getTranscodeDecision", ¶m_refs)?;
log::debug!("POST {url}");
let resp = self
.http
.post(url)
.json(info)
.send()
.await?
.error_for_status()?;
let text = resp.text().await?;
let wrapper: serde_json::Value =
serde_json::from_str(&text).map_err(|e| Error::Parse(format!("{e}: {text}")))?;
let inner = wrapper
.get("subsonic-response")
.ok_or_else(|| Error::Parse("Missing subsonic-response".into()))?;
let status = inner.get("status").and_then(|s| s.as_str()).unwrap_or("");
if status != "ok" {
let code = inner
.get("error")
.and_then(|e| e.get("code"))
.and_then(|c| c.as_i64())
.unwrap_or(0) as i32;
let msg = inner
.get("error")
.and_then(|e| e.get("message"))
.and_then(|m| m.as_str())
.unwrap_or("")
.to_string();
return Err(Error::Api(crate::error::SubsonicApiError {
code,
message: msg,
help_url: None,
}));
}
let decision = inner
.get("transcodeDecision")
.ok_or_else(|| Error::Parse("Missing 'transcodeDecision' in response".into()))?;
Ok(serde_json::from_value(decision.clone())?)
} else {
let param_refs: Vec<(&str, &str)> =
params.iter().map(|(k, v)| (*k, v.as_str())).collect();
let data = self
.get_response("getTranscodeDecision", ¶m_refs)
.await?;
let decision = data
.get("transcodeDecision")
.ok_or_else(|| Error::Parse("Missing 'transcodeDecision' in response".into()))?;
Ok(serde_json::from_value(decision.clone())?)
}
}
pub fn get_transcode_stream_url(
&self,
id: &str,
max_bit_rate: Option<i32>,
format: Option<&str>,
) -> Result<Url, Error> {
let mut params = vec![("id", id.to_string())];
if let Some(br) = max_bit_rate {
params.push(("maxBitRate", br.to_string()));
}
if let Some(f) = format {
params.push(("format", f.to_string()));
}
let param_refs: Vec<(&str, &str)> = params.iter().map(|(k, v)| (*k, v.as_str())).collect();
self.build_url("getTranscodeStream", ¶m_refs)
}
pub async fn get_transcode_stream(
&self,
id: &str,
max_bit_rate: Option<i32>,
format: Option<&str>,
) -> Result<Bytes, Error> {
let mut params = vec![("id", id.to_string())];
if let Some(br) = max_bit_rate {
params.push(("maxBitRate", br.to_string()));
}
if let Some(f) = format {
params.push(("format", f.to_string()));
}
let param_refs: Vec<(&str, &str)> = params.iter().map(|(k, v)| (*k, v.as_str())).collect();
self.get_bytes("getTranscodeStream", ¶m_refs).await
}
}