use async_trait::async_trait;
use bytes::Bytes;
use std::net::SocketAddr;
use std::sync::Arc;
use tokio::sync::Mutex;
use crate::session::RtpSession;
use crate::traits::MediaTransport;
use crate::transport::UdpRtpTransport;
use crate::Result;
pub struct RtpMediaTransport {
session: Arc<Mutex<RtpSession>>,
}
impl RtpMediaTransport {
pub fn new(session: RtpSession) -> Self {
Self {
session: Arc::new(Mutex::new(session)),
}
}
pub fn session(&self) -> &Arc<Mutex<RtpSession>> {
&self.session
}
pub async fn set_remote_addr(&self, addr: SocketAddr) -> Result<()> {
let mut session = self.session.lock().await;
session.set_remote_addr(addr).await;
let transport = session.transport();
if let Some(udp) = transport.as_any().downcast_ref::<UdpRtpTransport>() {
udp.set_remote_rtp_addr(addr).await;
}
Ok(())
}
}
#[async_trait]
impl MediaTransport for RtpMediaTransport {
async fn local_addr(&self) -> Result<SocketAddr> {
let session = self.session.lock().await;
session.local_addr()
}
async fn send_media(
&self,
payload_type: u8,
timestamp: u32,
payload: Bytes,
marker: bool,
) -> Result<()> {
let mut session = self.session.lock().await;
if session.get_payload_type() != payload_type {
session.set_payload_type(payload_type);
}
session.send_packet(timestamp, payload, marker).await
}
async fn close(&self) -> Result<()> {
let mut session = self.session.lock().await;
session.close().await?;
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::session::RtpSessionConfig;
#[tokio::test]
async fn test_rtp_media_transport() {
let config = RtpSessionConfig::default();
let session = RtpSession::new(config).await.unwrap();
let transport = RtpMediaTransport::new(session);
let addr = transport.local_addr().await.unwrap();
assert_ne!(addr.port(), 0);
let payload = Bytes::from_static(b"test payload");
let result = transport.send_media(0, 12345, payload, true).await;
assert!(result.is_ok());
let result = transport.close().await;
assert!(result.is_ok());
}
}