use ados_protocol::media_relay::{
RigWriteReply, WhepOfferReply, RIG_CAPABILITY, RIG_WRITE_METHOD, WHEP_CAPABILITY,
WHEP_CLOSE_METHOD, WHEP_OFFER_METHOD,
};
use super::*;
const RELAY_TIMEOUT: Duration = Duration::from_secs(12);
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct WhepAnswer {
pub sdp: String,
pub location: Option<String>,
}
fn args(entries: &[(&str, &str)]) -> Value {
Value::Map(
entries
.iter()
.map(|(k, v)| (Value::from(*k), Value::from(*v)))
.collect(),
)
}
impl PluginIpcClient {
pub async fn whep_offer(
&self,
camera_id: &str,
offer_sdp: &str,
) -> Result<WhepAnswer, ClientError> {
let args = args(&[("camera_id", camera_id), ("sdp", offer_sdp)]);
let reply = self
.send_request_within(WHEP_OFFER_METHOD, WHEP_CAPABILITY, args, RELAY_TIMEOUT)
.await?;
let reply: WhepOfferReply = decode_typed_reply(reply.args, WHEP_OFFER_METHOD)?;
Ok(WhepAnswer {
sdp: reply.sdp,
location: reply.location,
})
}
pub async fn whep_close(&self, location: &str) -> Result<(), ClientError> {
let args = args(&[("location", location)]);
let reply = self
.send_request_within(WHEP_CLOSE_METHOD, WHEP_CAPABILITY, args, RELAY_TIMEOUT)
.await?;
if let Some(error) = map_get_str(&reply.args, "error") {
return Err(ClientError::Rpc(format!("{error}: {WHEP_CLOSE_METHOD}")));
}
Ok(())
}
pub async fn put_rig(
&self,
rig: &serde_json::Value,
) -> Result<(u16, serde_json::Value), ClientError> {
let args = args(&[("rig_json", rig.to_string().as_str())]);
let reply = self
.send_request_within(RIG_WRITE_METHOD, RIG_CAPABILITY, args, RELAY_TIMEOUT)
.await?;
let reply: RigWriteReply = decode_typed_reply(reply.args, RIG_WRITE_METHOD)?;
let body = serde_json::from_str(&reply.body_json)
.map_err(|e| ClientError::Rpc(format!("{RIG_WRITE_METHOD} answer is not JSON: {e}")))?;
Ok((reply.status, body))
}
}