use cxx::SharedPtr;
use tokio::sync::oneshot;
use webrtc_sys::rtp_receiver as sys_rr;
use crate::{
imp::media_stream_track::new_media_stream_track, 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 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()
}
}