Overview
Interceptors allow you to intercept and process RTP and RTCP packets as they flow through the WebRTC stack. They enable advanced features like:
NACK (Negative Acknowledgment) for packet loss recovery
TWCC (Transport Wide Congestion Control) for bandwidth estimation
RTCP Sender/Receiver Reports for statistics
Custom packet processing and modification
FlexFEC forward error correction
Pion provides a default set of interceptors that handle most common use cases. You only need to configure interceptors manually for advanced scenarios.
Default Interceptors
Pion registers these interceptors by default:
NACK Generator & Responder
Automatically requests retransmission of lost packets and responds to NACK requests
RTCP Reports
Generates Sender and Receiver Reports for connection statistics
Stats Interceptor
Collects RTP stream statistics accessible via GetStats()
TWCC Sender
Generates Transport-Wide Congestion Control feedback for bandwidth estimation
Simulcast Extensions
Enables RTP header extensions needed for simulcast (MID, RID)
Using Default Interceptors
package main
import (
" github.com/pion/interceptor "
" github.com/pion/webrtc/v4 "
)
func main () {
// Create MediaEngine and InterceptorRegistry
m := & webrtc . MediaEngine {}
if err := m . RegisterDefaultCodecs (); err != nil {
panic ( err )
}
i := & interceptor . Registry {}
// Register default interceptors
if err := webrtc . RegisterDefaultInterceptors ( m , i ); err != nil {
panic ( err )
}
// Create API with MediaEngine and Interceptors
api := webrtc . NewAPI (
webrtc . WithMediaEngine ( m ),
webrtc . WithInterceptorRegistry ( i ),
)
// Create PeerConnection
peerConnection , err := api . NewPeerConnection ( webrtc . Configuration {})
if err != nil {
panic ( err )
}
defer peerConnection . Close ()
}
From interceptor.go:24-29 .
Configuring Default Interceptors
You can pass options to configure the default interceptors:
import (
" github.com/pion/interceptor "
" github.com/pion/logging "
" github.com/pion/webrtc/v4 "
)
m := & webrtc . MediaEngine {}
m . RegisterDefaultCodecs ()
i := & interceptor . Registry {}
// Create a logger factory
loggerFactory := logging . NewDefaultLoggerFactory ()
// Register with options
err := webrtc . RegisterDefaultInterceptorsWithOptions ( m , i ,
webrtc . WithInterceptorLoggerFactory ( loggerFactory ),
)
if err != nil {
panic ( err )
}
From interceptor.go:31-75 .
NACK Interceptor
NACK (Negative Acknowledgment) enables automatic retransmission of lost RTP packets.
Basic Configuration
import (
" github.com/pion/interceptor "
" github.com/pion/webrtc/v4 "
)
m := & webrtc . MediaEngine {}
m . RegisterDefaultCodecs ()
i := & interceptor . Registry {}
// Configure NACK
if err := webrtc . ConfigureNack ( m , i ); err != nil {
panic ( err )
}
From interceptor.go:142-168 .
NACK with Options
import (
" github.com/pion/interceptor/pkg/nack "
" github.com/pion/logging "
)
loggerFactory := logging . NewDefaultLoggerFactory ()
genOpts := [] nack . GeneratorOption {
nack . WithGeneratorLoggerFactory ( loggerFactory ),
}
respOpts := [] nack . ResponderOption {
nack . WithResponderLoggerFactory ( loggerFactory ),
}
err := webrtc . ConfigureNackWithOptions ( m , i , genOpts , respOpts ... )
From interceptor.go:147-168 .
NACK automatically registers the required RTCP feedback (nack and nack pli) to the MediaEngine.
TWCC (Transport-Wide Congestion Control)
TWCC provides fine-grained bandwidth estimation by tracking individual RTP packets.
import (
" github.com/pion/interceptor "
" github.com/pion/webrtc/v4 "
)
m := & webrtc . MediaEngine {}
m . RegisterDefaultCodecs ()
i := & interceptor . Registry {}
// Configure TWCC - generates TWCC feedback reports
if err := webrtc . ConfigureTWCCSender ( m , i ); err != nil {
panic ( err )
}
This registers:
Transport-CC header extension for video and audio
TWCC RTCP feedback
TWCC sender interceptor
From interceptor.go:195-228 .
TWCC with Options
import (
" github.com/pion/interceptor/pkg/twcc "
" github.com/pion/logging "
)
loggerFactory := logging . NewDefaultLoggerFactory ()
opts := [] twcc . Option {
twcc . WithLoggerFactory ( loggerFactory ),
}
err := webrtc . ConfigureTWCCSenderWithOptions ( m , i , opts ... )
From interceptor.go:201-228 .
If you only want to add TWCC header extensions (to let the remote peer generate reports):
// Only add header extension, don't generate reports
if err := webrtc . ConfigureTWCCHeaderExtensionSender ( m , i ); err != nil {
panic ( err )
}
From interceptor.go:170-193 .
RTCP Reports
Generate Sender and Receiver Reports for connection statistics.
import (
" github.com/pion/interceptor "
" github.com/pion/webrtc/v4 "
)
m := & webrtc . MediaEngine {}
m . RegisterDefaultCodecs ()
i := & interceptor . Registry {}
// Configure RTCP Reports
if err := webrtc . ConfigureRTCPReports ( i ); err != nil {
panic ( err )
}
From interceptor.go:116-140 .
RTCP Reports with Options
import (
" github.com/pion/interceptor/pkg/report "
" github.com/pion/logging "
)
loggerFactory := logging . NewDefaultLoggerFactory ()
recvOpts := [] report . ReceiverOption {
report . WithReceiverLoggerFactory ( loggerFactory ),
}
sendOpts := [] report . SenderOption {
report . WithSenderLoggerFactory ( loggerFactory ),
}
err := webrtc . ConfigureRTCPReportsWithOptions ( i , recvOpts , sendOpts ... )
Stats Interceptor
Collect detailed RTP stream statistics:
import (
" github.com/pion/interceptor "
" github.com/pion/webrtc/v4 "
)
m := & webrtc . MediaEngine {}
m . RegisterDefaultCodecs ()
i := & interceptor . Registry {}
// Configure Stats
if err := webrtc . ConfigureStatsInterceptor ( i ); err != nil {
panic ( err )
}
api := webrtc . NewAPI (
webrtc . WithMediaEngine ( m ),
webrtc . WithInterceptorRegistry ( i ),
)
peerConnection , _ := api . NewPeerConnection ( webrtc . Configuration {})
// Later, get stats
stats := peerConnection . GetStats ()
From interceptor.go:77-95 .
Simulcast Extensions
Enable RTP header extensions needed for simulcast:
import (
" github.com/pion/interceptor "
" github.com/pion/webrtc/v4 "
)
m := & webrtc . MediaEngine {}
m . RegisterDefaultCodecs ()
// Configure simulcast extensions (MID, RID, Repair RID)
if err := webrtc . ConfigureSimulcastExtensionHeaders ( m ); err != nil {
panic ( err )
}
This registers:
sdp.SDESMidURI - Media stream identification
sdp.SDESRTPStreamIDURI - RTP stream ID
sdp.SDESRepairRTPStreamIDURI - Repair stream ID
From interceptor.go:252-269 .
FlexFEC (Forward Error Correction)
FlexFEC adds redundancy to reduce packet loss impact:
import (
" github.com/pion/interceptor "
" github.com/pion/interceptor/pkg/flexfec "
" github.com/pion/webrtc/v4 "
)
m := & webrtc . MediaEngine {}
m . RegisterDefaultCodecs ()
i := & interceptor . Registry {}
// Configure FlexFEC with payload type 125
options := [] flexfec . FecOption {}
err := webrtc . ConfigureFlexFEC03 (
125 , // payload type
m ,
i ,
options ... ,
)
if err != nil {
panic ( err )
}
FlexFEC interceptor must be registered before other interceptors that modify RTP packets (like TWCC), so that FEC packets are not modified.
From interceptor.go:271-304 .
RFC 8888 Congestion Control Feedback
Register congestion control feedback as defined in RFC 8888:
import (
" github.com/pion/interceptor "
" github.com/pion/interceptor/pkg/rfc8888 "
" github.com/pion/webrtc/v4 "
)
m := & webrtc . MediaEngine {}
m . RegisterDefaultCodecs ()
i := & interceptor . Registry {}
options := [] rfc8888 . Option {}
err := webrtc . ConfigureCongestionControlFeedback ( m , i , options ... )
if err != nil {
panic ( err )
}
From interceptor.go:230-250 .
Custom Interceptor
You can create custom interceptors to process RTP/RTCP packets:
import (
" github.com/pion/interceptor "
" github.com/pion/rtp "
)
// Custom interceptor that logs all RTP packets
type LoggingInterceptor struct {
interceptor . NoOp
}
func ( l * LoggingInterceptor ) BindLocalStream (
info * interceptor . StreamInfo ,
writer interceptor . RTPWriter ,
) interceptor . RTPWriter {
return interceptor . RTPWriterFunc ( func (
header * rtp . Header ,
payload [] byte ,
attributes interceptor . Attributes ,
) ( int , error ) {
fmt . Printf ( "Sending RTP: SSRC= %d PT= %d SN= %d \n " ,
header . SSRC , header . PayloadType , header . SequenceNumber )
return writer . Write ( header , payload , attributes )
})
}
func ( l * LoggingInterceptor ) BindRemoteStream (
info * interceptor . StreamInfo ,
reader interceptor . RTPReader ,
) interceptor . RTPReader {
return interceptor . RTPReaderFunc ( func (
b [] byte ,
a interceptor . Attributes ,
) ( int , interceptor . Attributes , error ) {
n , attr , err := reader . Read ( b , a )
if err == nil {
fmt . Printf ( "Received RTP packet ( %d bytes) \n " , n )
}
return n , attr , err
})
}
// Register the custom interceptor
i := & interceptor . Registry {}
i . Add ( & LoggingInterceptor {})
Complete Example
Full Interceptor Configuration
package main
import (
" fmt "
" github.com/pion/interceptor "
" github.com/pion/interceptor/pkg/nack "
" github.com/pion/logging "
" github.com/pion/webrtc/v4 "
)
func main () {
// Create MediaEngine
m := & webrtc . MediaEngine {}
if err := m . RegisterDefaultCodecs (); err != nil {
panic ( err )
}
// Create InterceptorRegistry
i := & interceptor . Registry {}
// Create logger factory
loggerFactory := logging . NewDefaultLoggerFactory ()
// Configure NACK with logging
genOpts := [] nack . GeneratorOption {
nack . WithGeneratorLoggerFactory ( loggerFactory ),
}
respOpts := [] nack . ResponderOption {
nack . WithResponderLoggerFactory ( loggerFactory ),
}
if err := webrtc . ConfigureNackWithOptions ( m , i , genOpts , respOpts ... ); err != nil {
panic ( err )
}
// Configure RTCP Reports
if err := webrtc . ConfigureRTCPReports ( i ); err != nil {
panic ( err )
}
// Configure simulcast extensions
if err := webrtc . ConfigureSimulcastExtensionHeaders ( m ); err != nil {
panic ( err )
}
// Configure Stats
if err := webrtc . ConfigureStatsInterceptor ( i ); err != nil {
panic ( err )
}
// Configure TWCC
if err := webrtc . ConfigureTWCCSender ( m , i ); err != nil {
panic ( err )
}
// Create API
api := webrtc . NewAPI (
webrtc . WithMediaEngine ( m ),
webrtc . WithInterceptorRegistry ( i ),
)
// Create PeerConnection
config := webrtc . Configuration {
ICEServers : [] webrtc . ICEServer {
{ URLs : [] string { "stun:stun.l.google.com:19302" }},
},
}
peerConnection , err := api . NewPeerConnection ( config )
if err != nil {
panic ( err )
}
defer peerConnection . Close ()
fmt . Println ( "PeerConnection created with interceptors" )
// Later: access stats
stats := peerConnection . GetStats ()
fmt . Printf ( "Stats available: %v \n " , stats )
}
Interceptor Order
The order of interceptors matters:
FlexFEC - Must be first if used, so FEC packets aren’t modified
NACK Responder - Should be early to handle retransmissions
TWCC - Add sequence numbers to packets
Stats - Collect statistics
RTCP Reports - Generate reports
NACK Generator - Request retransmissions
RegisterDefaultInterceptors handles the correct ordering automatically.
MediaEngine Configure codecs and capabilities
SettingEngine Advanced configuration options