Overview
TrackRemote represents a single inbound source of media. It provides methods to read RTP packets, access track metadata, and handle retransmission (RTX) streams.
Type Definition
type TrackRemote struct {
mu sync . RWMutex
id string
streamID string
payloadType PayloadType
kind RTPCodecType
ssrc SSRC
rtxSsrc SSRC
codec RTPCodecParameters
params RTPParameters
rid string
receiver * RTPReceiver
peekedPackets [] * peekedPacket
audioPlayoutStatsProviders [] AudioPlayoutStatsProvider
}
Methods
Returns the unique identifier for this Track. This should be unique for the stream, but doesn’t have to be globally unique. A common example would be ‘audio’ or ‘video’ and StreamID would be ‘desktop’ or ‘webcam’.
func ( t * TrackRemote ) ID () string
RID
Gets the RTP Stream ID of this Track. With Simulcast you will have multiple tracks with the same ID, but different RID values. In many cases a TrackRemote will not have an RID, so it is important to assert it is non-zero.
func ( t * TrackRemote ) RID () string
The RTP stream identifier, or empty string if not set
PayloadType
Gets the PayloadType of the track.
func ( t * TrackRemote ) PayloadType () PayloadType
The RTP payload type number
Kind
Gets the Kind of the track (audio or video).
func ( t * TrackRemote ) Kind () RTPCodecType
Either RTPCodecTypeAudio or RTPCodecTypeVideo
StreamID
Returns the group this track belongs to. This must be unique.
func ( t * TrackRemote ) StreamID () string
SSRC
Gets the SSRC of the track.
func ( t * TrackRemote ) SSRC () SSRC
The synchronization source identifier
Msid
Gets the Msid (Media Stream ID) of the track.
func ( t * TrackRemote ) Msid () string
The media stream ID in format “streamID trackID”
Codec
Gets the Codec of the track.
func ( t * TrackRemote ) Codec () RTPCodecParameters
The codec parameters including mime type, clock rate, and format parameters
Read
Reads data from the track.
func ( t * TrackRemote ) Read ( b [] byte ) ( n int , attributes interceptor . Attributes , err error )
Buffer to read RTP packet data into
Interceptor attributes associated with the packet
Returns io.EOF if receiver is closed, or other errors on read failure
This method automatically handles RTX (retransmission) packets if available, transparently merging them into the main stream.
ReadRTP
A convenience method that wraps Read and unmarshals for you.
func ( t * TrackRemote ) ReadRTP () ( * rtp . Packet , interceptor . Attributes , error )
The unmarshaled RTP packet
Returns error if read or unmarshal fails
Basic Usage
With Attributes
for {
packet , attributes , err := track . ReadRTP ()
if err != nil {
return err
}
fmt . Printf ( "Received RTP: SSRC= %d , Seq= %d , Timestamp= %d \n " ,
packet . SSRC , packet . SequenceNumber , packet . Timestamp )
// Process packet payload
processMedia ( packet . Payload )
}
SetReadDeadline
Sets the max amount of time the RTP stream will block before returning. 0 is forever.
func ( t * TrackRemote ) SetReadDeadline ( deadline time . Time ) error
The deadline time. Zero value means no deadline.
Returns error if setting the deadline fails
RtxSSRC
Returns the RTX SSRC for a track, or 0 if track does not have a separate RTX stream.
func ( t * TrackRemote ) RtxSSRC () SSRC
The RTX synchronization source identifier, or 0 if RTX is not enabled
HasRTX
Returns true if the track has a separate RTX stream.
func ( t * TrackRemote ) HasRTX () bool
True if RTX is enabled for this track
Usage Examples
Basic Track Handling
peerConnection . OnTrack ( func ( track * webrtc . TrackRemote , receiver * webrtc . RTPReceiver ) {
fmt . Printf ( "Track started: \n " )
fmt . Printf ( " ID: %s \n " , track . ID ())
fmt . Printf ( " Stream ID: %s \n " , track . StreamID ())
fmt . Printf ( " Kind: %s \n " , track . Kind ())
fmt . Printf ( " SSRC: %d \n " , track . SSRC ())
fmt . Printf ( " Codec: %s \n " , track . Codec (). MimeType )
for {
packet , _ , err := track . ReadRTP ()
if err != nil {
return
}
// Process RTP packet
fmt . Printf ( "RTP: %d bytes \n " , len ( packet . Payload ))
}
})
Saving Track to File
peerConnection . OnTrack ( func ( track * webrtc . TrackRemote , receiver * webrtc . RTPReceiver ) {
codec := track . Codec ()
if codec . MimeType != webrtc . MimeTypeVP8 {
return
}
// Create output file
file , err := os . Create ( "output.ivf" )
if err != nil {
panic ( err )
}
defer file . Close ()
// Write IVF header
ivfWriter , err := ivfwriter . New ( file , codec . ClockRate )
if err != nil {
panic ( err )
}
// Read and save packets
for {
packet , _ , err := track . ReadRTP ()
if err != nil {
return
}
if err := ivfWriter . WriteRTP ( packet ); err != nil {
return
}
}
})
Handling Simulcast Tracks
peerConnection . OnTrack ( func ( track * webrtc . TrackRemote , receiver * webrtc . RTPReceiver ) {
rid := track . RID ()
if rid != "" {
fmt . Printf ( "Simulcast track with RID: %s \n " , rid )
}
// Get all simulcast tracks
tracks := receiver . Tracks ()
fmt . Printf ( "Total tracks in receiver: %d \n " , len ( tracks ))
for _ , t := range tracks {
fmt . Printf ( " RID: %s , SSRC: %d \n " , t . RID (), t . SSRC ())
}
})
Checking RTX Support
peerConnection . OnTrack ( func ( track * webrtc . TrackRemote , receiver * webrtc . RTPReceiver ) {
if track . HasRTX () {
fmt . Printf ( "Track has RTX support \n " )
fmt . Printf ( "Main SSRC: %d \n " , track . SSRC ())
fmt . Printf ( "RTX SSRC: %d \n " , track . RtxSSRC ())
} else {
fmt . Printf ( "No RTX support \n " )
}
for {
packet , attributes , err := track . ReadRTP ()
if err != nil {
return
}
// Check if this packet was retransmitted
if rtxSsrc , ok := attributes . Get ( webrtc . AttributeRtxSsrc ).( uint32 ); ok {
fmt . Printf ( "Retransmitted packet from SSRC %d \n " , rtxSsrc )
}
}
})
Setting Read Timeout
peerConnection . OnTrack ( func ( track * webrtc . TrackRemote , receiver * webrtc . RTPReceiver ) {
// Set 5 second timeout
deadline := time . Now (). Add ( 5 * time . Second )
if err := track . SetReadDeadline ( deadline ); err != nil {
panic ( err )
}
packet , _ , err := track . ReadRTP ()
if err != nil {
if netErr , ok := err .( net . Error ); ok && netErr . Timeout () {
fmt . Println ( "Read timeout" )
}
return
}
// Clear deadline
track . SetReadDeadline ( time . Time {})
})
Forwarding Track to Another Peer
// Receive track from one peer
peerConnection1 . OnTrack ( func ( remoteTrack * webrtc . TrackRemote , receiver * webrtc . RTPReceiver ) {
// Create local track to forward
localTrack , err := webrtc . NewTrackLocalStaticRTP (
remoteTrack . Codec (). RTPCodecCapability ,
remoteTrack . ID (),
remoteTrack . StreamID (),
)
if err != nil {
panic ( err )
}
// Add to second peer connection
_ , err = peerConnection2 . AddTrack ( localTrack )
if err != nil {
panic ( err )
}
// Forward packets
for {
packet , _ , err := remoteTrack . ReadRTP ()
if err != nil {
return
}
if err := localTrack . WriteRTP ( packet ); err != nil {
return
}
}
})
See Also