Skip to main content

Overview

RTPReceiver allows an application to inspect the receipt of a TrackRemote. It manages inbound RTP streams including demuxing, RTCP feedback, and support for simulcast and RTX.

Type Definition

type RTPReceiver struct {
    kind       RTPCodecType
    transport  *DTLSTransport
    tracks     []trackStreams
    closed     atomic.Bool
    closedChan chan any
    received   chan any
    mu         sync.RWMutex
    tr         *RTPTransceiver
    api        *API
    rtxPool    sync.Pool
    log        logging.LeveledLogger
}

Constructor

NewRTPReceiver

Constructs a new RTPReceiver.
func (api *API) NewRTPReceiver(kind RTPCodecType, transport *DTLSTransport) (*RTPReceiver, error)
kind
RTPCodecType
required
The codec type (audio or video)
transport
*DTLSTransport
required
The DTLS transport to use for receiving
receiver
*RTPReceiver
The newly created RTPReceiver
error
error
Returns error if transport is nil

Methods

Transport

Returns the currently-configured DTLSTransport or nil if one has not yet been configured.
func (r *RTPReceiver) Transport() *DTLSTransport
transport
*DTLSTransport
The associated DTLS transport

GetParameters

Describes the current configuration for the encoding and transmission of media on the receiver’s track.
func (r *RTPReceiver) GetParameters() RTPParameters
parameters
RTPParameters
The current receive parameters including codecs and header extensions

Track

Returns the RTPReceiver’s TrackRemote.
func (r *RTPReceiver) Track() *TrackRemote
track
*TrackRemote
The remote track, or nil if there are multiple tracks (simulcast)
For simulcast streams with multiple tracks, use the Tracks() method instead.

Tracks

Returns the RTPReceiver tracks. An RTPReceiver may have multiple tracks to support Simulcast.
func (r *RTPReceiver) Tracks() []*TrackRemote
tracks
[]*TrackRemote
All remote tracks associated with this receiver

RTPTransceiver

Returns the RTPTransceiver this RTPReceiver belongs to, or nil if none.
func (r *RTPReceiver) RTPTransceiver() *RTPTransceiver
transceiver
*RTPTransceiver
The associated transceiver

Receive

Initializes the track and starts all the transports.
func (r *RTPReceiver) Receive(parameters RTPReceiveParameters) error
parameters
RTPReceiveParameters
required
The receive parameters to configure
error
error
Returns error if:
  • Receive already called
  • Track stream not found for SSRC
  • Stream initialization fails

Read

Reads incoming RTCP for this RTPReceiver.
func (r *RTPReceiver) Read(b []byte) (n int, a interceptor.Attributes, err error)
b
[]byte
required
Buffer to read RTCP data into
n
int
Number of bytes read
attributes
interceptor.Attributes
Interceptor attributes associated with the packet
error
error
Returns error if read fails or receiver is closed
If the receiver has multiple tracks (simulcast), this method will log an error recommending to use ReadSimulcast instead.

ReadRTCP

A convenience method that wraps Read and unmarshal for you. It also runs any configured interceptors.
func (r *RTPReceiver) ReadRTCP() ([]rtcp.Packet, interceptor.Attributes, error)
packets
[]rtcp.Packet
The unmarshaled RTCP packets
attributes
interceptor.Attributes
Interceptor attributes
error
error
Returns error if read or unmarshal fails
for {
    packets, _, err := receiver.ReadRTCP()
    if err != nil {
        return err
    }
    
    for _, packet := range packets {
        switch p := packet.(type) {
        case *rtcp.SenderReport:
            fmt.Printf("Received SR: %+v\n", p)
        case *rtcp.SourceDescription:
            fmt.Printf("Received SDES: %+v\n", p)
        }
    }
}

ReadSimulcast

Reads incoming RTCP for this RTPReceiver for given RID.
func (r *RTPReceiver) ReadSimulcast(b []byte, rid string) (n int, a interceptor.Attributes, err error)
b
[]byte
required
Buffer to read RTCP data into
rid
string
required
The RTP stream identifier to read RTCP for
error
error
Returns error if track stream not found for RID

ReadSimulcastRTCP

A convenience method that wraps ReadSimulcast and unmarshal for you.
func (r *RTPReceiver) ReadSimulcastRTCP(rid string) ([]rtcp.Packet, interceptor.Attributes, error)
rid
string
required
The RTP stream identifier

Stop

Irreversibly stops the RTPReceiver.
func (r *RTPReceiver) Stop() error
error
error
Returns error if stopping fails
Stopping a receiver closes all associated RTP and RTCP streams and unbinds all interceptors.

SetReadDeadline

Sets the max amount of time the RTCP stream will block before returning. 0 is forever.
func (r *RTPReceiver) SetReadDeadline(t time.Time) error
t
time.Time
required
The deadline time. Zero value means no deadline.

SetReadDeadlineSimulcast

Sets the max amount of time the RTCP stream for a given RID will block before returning. 0 is forever.
func (r *RTPReceiver) SetReadDeadlineSimulcast(deadline time.Time, rid string) error
deadline
time.Time
required
The deadline time
rid
string
required
The RTP stream identifier
error
error
Returns error if track stream not found for RID

Usage Examples

Handling Incoming Tracks

peerConnection.OnTrack(func(track *webrtc.TrackRemote, receiver *webrtc.RTPReceiver) {
    fmt.Printf("Track has started, of type %d: %s\n", track.PayloadType(), track.Codec().MimeType)
    
    // Read RTP packets
    for {
        pkt, _, err := track.ReadRTP()
        if err != nil {
            return
        }
        
        // Process RTP packet
        fmt.Printf("Received RTP packet: %d bytes\n", len(pkt.Payload))
    }
})

Reading RTCP Feedback

peerConnection.OnTrack(func(track *webrtc.TrackRemote, receiver *webrtc.RTPReceiver) {
    // Read RTCP packets in separate goroutine
    go func() {
        for {
            packets, _, err := receiver.ReadRTCP()
            if err != nil {
                return
            }
            
            for _, pkt := range packets {
                switch p := pkt.(type) {
                case *rtcp.SenderReport:
                    fmt.Printf("SR SSRC: %d, NTP: %d\n", p.SSRC, p.NTPTime)
                }
            }
        }
    }()
})

Handling Simulcast Tracks

peerConnection.OnTrack(func(track *webrtc.TrackRemote, receiver *webrtc.RTPReceiver) {
    // Get all tracks (for simulcast)
    tracks := receiver.Tracks()
    fmt.Printf("Receiver has %d tracks\n", len(tracks))
    
    for _, t := range tracks {
        rid := t.RID()
        fmt.Printf("Track RID: %s, SSRC: %d\n", rid, t.SSRC())
        
        // Read RTCP for specific RID
        go func(r string) {
            for {
                packets, _, err := receiver.ReadSimulcastRTCP(r)
                if err != nil {
                    return
                }
                
                // Handle RTCP for this specific simulcast layer
                for _, pkt := range packets {
                    fmt.Printf("RTCP for RID %s: %T\n", r, pkt)
                }
            }
        }(rid)
    }
})

Using RTX (Retransmission)

peerConnection.OnTrack(func(track *webrtc.TrackRemote, receiver *webrtc.RTPReceiver) {
    if track.HasRTX() {
        fmt.Printf("Track has RTX support, RTX SSRC: %d\n", track.RtxSSRC())
    }
    
    // RTX packets are automatically handled and merged into the main stream
    for {
        pkt, attributes, err := track.ReadRTP()
        if err != nil {
            return
        }
        
        // Check if packet was received via RTX
        if rtxSsrc, ok := attributes.Get(webrtc.AttributeRtxSsrc).(uint32); ok {
            fmt.Printf("Packet received via RTX from SSRC %d\n", rtxSsrc)
        }
    }
})

See Also

Build docs developers (and LLMs) love