use cxx::SharedPtr;
use tokio::sync::oneshot;
use webrtc_sys::rtp_receiver as sys_rr;
use crate::{
imp::{media_stream as imp_ms, media_stream_track::new_media_stream_track},
media_stream::MediaStream,
media_stream_track::MediaStreamTrack,
rtp_parameters::RtpParameters,
stats::RtcStats,
RtcError, RtcErrorType,
};
#[derive(Clone)]
pub struct RtpReceiver {
pub(crate) sys_handle: SharedPtr<sys_rr::ffi::RtpReceiver>,
}
impl RtpReceiver {
pub fn track(&self) -> Option<MediaStreamTrack> {
let track_handle = self.sys_handle.track();
if track_handle.is_null() {
return None;
}
Some(new_media_stream_track(track_handle))
}
pub fn stream_ids(&self) -> Vec<String> {
self.sys_handle.stream_ids()
}
pub fn streams(&self) -> Vec<MediaStream> {
self.sys_handle
.streams()
.into_iter()
.map(|s| MediaStream { handle: imp_ms::MediaStream { sys_handle: s.ptr } })
.collect()
}
pub async fn get_stats(&self) -> Result<Vec<RtcStats>, RtcError> {
let (tx, rx) = oneshot::channel::<Result<Vec<RtcStats>, RtcError>>();
let ctx = Box::new(sys_rr::ReceiverContext(Box::new(tx)));
self.sys_handle.get_stats(ctx, |ctx, stats| {
let tx = ctx.0.downcast::<oneshot::Sender<Result<Vec<RtcStats>, RtcError>>>().unwrap();
if stats.is_empty() {
let _ = tx.send(Ok(vec![]));
return;
}
let vec = serde_json::from_str(&stats).unwrap();
let _ = tx.send(Ok(vec));
});
rx.await.map_err(|_| RtcError {
error_type: RtcErrorType::Internal,
message: "get_stats cancelled".to_owned(),
})?
}
pub fn parameters(&self) -> RtpParameters {
self.sys_handle.get_parameters().into()
}
}