1 use crate::error::*; 2 use crate::stream_info::StreamInfo; 3 use crate::*; 4 5 use std::sync::Arc; 6 7 /// Chain is an interceptor that runs all child interceptors in order. 8 #[derive(Default)] 9 pub struct Chain { 10 interceptors: Vec<Arc<dyn Interceptor + Send + Sync>>, 11 } 12 13 impl Chain { 14 /// new returns a new Chain interceptor. new(interceptors: Vec<Arc<dyn Interceptor + Send + Sync>>) -> Self15 pub fn new(interceptors: Vec<Arc<dyn Interceptor + Send + Sync>>) -> Self { 16 Chain { interceptors } 17 } 18 add(&mut self, icpr: Arc<dyn Interceptor + Send + Sync>)19 pub fn add(&mut self, icpr: Arc<dyn Interceptor + Send + Sync>) { 20 self.interceptors.push(icpr); 21 } 22 } 23 24 #[async_trait] 25 impl Interceptor for Chain { 26 /// bind_rtcp_reader lets you modify any incoming RTCP packets. It is called once per sender/receiver, however this might 27 /// change in the future. The returned method will be called once per packet batch. bind_rtcp_reader( &self, mut reader: Arc<dyn RTCPReader + Send + Sync>, ) -> Arc<dyn RTCPReader + Send + Sync>28 async fn bind_rtcp_reader( 29 &self, 30 mut reader: Arc<dyn RTCPReader + Send + Sync>, 31 ) -> Arc<dyn RTCPReader + Send + Sync> { 32 for icpr in &self.interceptors { 33 reader = icpr.bind_rtcp_reader(reader).await; 34 } 35 reader 36 } 37 38 /// bind_rtcp_writer lets you modify any outgoing RTCP packets. It is called once per PeerConnection. The returned method 39 /// will be called once per packet batch. bind_rtcp_writer( &self, mut writer: Arc<dyn RTCPWriter + Send + Sync>, ) -> Arc<dyn RTCPWriter + Send + Sync>40 async fn bind_rtcp_writer( 41 &self, 42 mut writer: Arc<dyn RTCPWriter + Send + Sync>, 43 ) -> Arc<dyn RTCPWriter + Send + Sync> { 44 for icpr in &self.interceptors { 45 writer = icpr.bind_rtcp_writer(writer).await; 46 } 47 writer 48 } 49 50 /// bind_local_stream lets you modify any outgoing RTP packets. It is called once for per LocalStream. The returned method 51 /// will be called once per rtp packet. bind_local_stream( &self, info: &StreamInfo, mut writer: Arc<dyn RTPWriter + Send + Sync>, ) -> Arc<dyn RTPWriter + Send + Sync>52 async fn bind_local_stream( 53 &self, 54 info: &StreamInfo, 55 mut writer: Arc<dyn RTPWriter + Send + Sync>, 56 ) -> Arc<dyn RTPWriter + Send + Sync> { 57 for icpr in &self.interceptors { 58 writer = icpr.bind_local_stream(info, writer).await; 59 } 60 writer 61 } 62 63 /// unbind_local_stream is called when the Stream is removed. It can be used to clean up any data related to that track. unbind_local_stream(&self, info: &StreamInfo)64 async fn unbind_local_stream(&self, info: &StreamInfo) { 65 for icpr in &self.interceptors { 66 icpr.unbind_local_stream(info).await; 67 } 68 } 69 70 /// bind_remote_stream lets you modify any incoming RTP packets. It is called once for per RemoteStream. The returned method 71 /// will be called once per rtp packet. bind_remote_stream( &self, info: &StreamInfo, mut reader: Arc<dyn RTPReader + Send + Sync>, ) -> Arc<dyn RTPReader + Send + Sync>72 async fn bind_remote_stream( 73 &self, 74 info: &StreamInfo, 75 mut reader: Arc<dyn RTPReader + Send + Sync>, 76 ) -> Arc<dyn RTPReader + Send + Sync> { 77 for icpr in &self.interceptors { 78 reader = icpr.bind_remote_stream(info, reader).await; 79 } 80 reader 81 } 82 83 /// unbind_remote_stream is called when the Stream is removed. It can be used to clean up any data related to that track. unbind_remote_stream(&self, info: &StreamInfo)84 async fn unbind_remote_stream(&self, info: &StreamInfo) { 85 for icpr in &self.interceptors { 86 icpr.unbind_remote_stream(info).await; 87 } 88 } 89 90 /// close closes the Interceptor, cleaning up any data if necessary. close(&self) -> Result<()>91 async fn close(&self) -> Result<()> { 92 let mut errs = vec![]; 93 for icpr in &self.interceptors { 94 if let Err(err) = icpr.close().await { 95 errs.push(err); 96 } 97 } 98 flatten_errs(errs) 99 } 100 } 101