Interceptor

Trait Interceptor 

Source
pub trait Interceptor: Protocol<TaggedPacket, TaggedPacket, (), Rout = TaggedPacket, Wout = TaggedPacket, Eout = (), Time = Instant, Error = Error> + Sized {
    // Required methods
    fn bind_local_stream(&mut self, info: &StreamInfo);
    fn unbind_local_stream(&mut self, info: &StreamInfo);
    fn bind_remote_stream(&mut self, info: &StreamInfo);
    fn unbind_remote_stream(&mut self, info: &StreamInfo);

    // Provided method
    fn with<O, F>(self, f: F) -> O
       where F: FnOnce(Self) -> O,
             O: Interceptor { ... }
}
Expand description

Trait for RTP/RTCP interceptors with fixed Protocol type parameters.

Interceptor is a marker trait that requires implementors to also implement sansio::Protocol with specific fixed type parameters for RTP/RTCP processing:

This trait adds stream binding methods and provides a with() method for composable chaining of interceptors.

§Creating Custom Interceptors

The easiest way to create a custom interceptor is using the derive macros:

use rtc_interceptor::{Interceptor, interceptor, TaggedPacket, Packet, StreamInfo};
use std::collections::VecDeque;

#[derive(Interceptor)]
pub struct MyInterceptor<P: Interceptor> {
    #[next]
    next: P,  // The next interceptor in the chain
    buffer: VecDeque<TaggedPacket>,
}

#[interceptor]
impl<P: Interceptor> MyInterceptor<P> {
    #[overrides]
    fn handle_read(&mut self, msg: TaggedPacket) -> Result<(), Self::Error> {
        // Custom logic here
        self.next.handle_read(msg)
    }
}

The #[derive(Interceptor)] macro requires a #[next] field that contains the next interceptor in the chain. The #[interceptor] attribute on the impl block generates the Protocol and Interceptor trait implementations, delegating non-overridden methods to the next interceptor.

Use #[overrides] to mark methods with custom implementations.

§Manual Implementation

For more control, you can implement the traits manually:

pub struct MyInterceptor<P> {
    inner: P,
}

impl<P: Interceptor> Protocol<TaggedPacket, TaggedPacket, ()> for MyInterceptor<P> {
    type Rout = TaggedPacket;
    type Wout = TaggedPacket;
    type Eout = ();
    type Time = Instant;
    type Error = shared::error::Error;
    // ... implement Protocol methods
}

impl<P: Interceptor> Interceptor for MyInterceptor<P> {
    fn bind_local_stream(&mut self, _info: &StreamInfo) {}
    fn unbind_local_stream(&mut self, _info: &StreamInfo) {}
    fn bind_remote_stream(&mut self, _info: &StreamInfo) {}
    fn unbind_remote_stream(&mut self, _info: &StreamInfo) {}
}

§Using with Registry

let chain = Registry::new()
    .with(|inner| MyInterceptor { next: inner, buffer: VecDeque::new() });

Required Methods§

Source

fn bind_local_stream(&mut self, info: &StreamInfo)

bind_local_stream lets you modify any outgoing RTP packets. It is called once for per LocalStream. The returned method will be called once per rtp packet.

Source

fn unbind_local_stream(&mut self, info: &StreamInfo)

unbind_local_stream is called when the Stream is removed. It can be used to clean up any data related to that track.

Source

fn bind_remote_stream(&mut self, info: &StreamInfo)

bind_remote_stream lets you modify any incoming RTP packets. It is called once for per RemoteStream. The returned method will be called once per rtp packet.

Source

fn unbind_remote_stream(&mut self, info: &StreamInfo)

unbind_remote_stream is called when the Stream is removed. It can be used to clean up any data related to that track.

Provided Methods§

Source

fn with<O, F>(self, f: F) -> O
where F: FnOnce(Self) -> O, O: Interceptor,

Wrap this interceptor with another layer.

The wrapper function receives self and returns a new interceptor that wraps it.

§Example
use std::time::Duration;
use rtc_interceptor::{NoopInterceptor, SenderReportBuilder};

// Using the builder pattern (recommended)
let chain = NoopInterceptor::new()
    .with(SenderReportBuilder::new().with_interval(Duration::from_secs(1)).build());

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§