type Opus struct { // RTP payload type (96–127). PayloadTyp uint8 // Number of audio channels (1 = mono, 2 = stereo). // Determined from the sprop-stereo fmtp parameter. ChannelCount int}
// find the Opus media and formatvar forma *format.Opusmedi := desc.FindFormat(&forma)if medi == nil { panic("media not found")}// create decoderrtpDec, err := forma.CreateDecoder()if err != nil { panic(err)}_, err = c.Setup(desc.BaseURL, medi, 0, 0)if err != nil { panic(err)}// called when a RTP packet arrivesc.OnPacketRTP(medi, forma, func(pkt *rtp.Packet) { pts, ok := c.PacketPTS(medi, pkt) if !ok { log.Printf("waiting for timestamp") return } // extract Opus packets from RTP packets op, err := rtpDec.Decode(pkt) if err != nil { log.Printf("ERR: %v", err) return } log.Printf("received Opus packet with PTS %v size %d", pts, len(op))})
type MPEG4Audio struct { // RTP payload type (96–127). PayloadTyp uint8 ProfileLevelID int // Parsed AudioSpecificConfig from the config fmtp parameter. // Contains sample rate, channel count, and codec profile. Config *mpeg4audio.AudioSpecificConfig SizeLength int IndexLength int IndexDeltaLength int}
// find the MPEG-4 audio media and formatvar forma *format.MPEG4Audiomedi := desc.FindFormat(&forma)if medi == nil { panic("media not found")}// create decoderrtpDec, err := forma.CreateDecoder()if err != nil { panic(err)}_, err = c.Setup(desc.BaseURL, medi, 0, 0)if err != nil { panic(err)}// called when a RTP packet arrivesc.OnPacketRTP(medi, forma, func(pkt *rtp.Packet) { pts, ok := c.PacketPTS(medi, pkt) if !ok { log.Printf("waiting for timestamp") return } // extract access units from RTP packets aus, err := rtpDec.Decode(pkt) if err != nil { log.Printf("ERR: %v", err) return } // one RTP packet may contain multiple access units for _, au := range aus { log.Printf("received access unit with PTS %v size %d", pts, len(au)) }})
The forma.Config field contains the parsed AudioSpecificConfig, including SampleRate and ChannelCount. Check this before configuring any downstream AAC decoder.
The standard static payload types (0 = PCMU, 8 = PCMA) are detected automatically from the SDP. Dynamic payload types support non-standard sample rates.
// declare a PCMU stream for recordingforma := &format.G711{ MULaw: true, // PCMU SampleRate: 8000, ChannelCount: 1,}// — or detect while playing back —var forma *format.G711medi := desc.FindFormat(&forma)if medi == nil { panic("media not found")}rtpDec, err := forma.CreateDecoder()if err != nil { panic(err)}_, err = c.Setup(desc.BaseURL, medi, 0, 0)if err != nil { panic(err)}c.OnPacketRTP(medi, forma, func(pkt *rtp.Packet) { pts, ok := c.PacketPTS(medi, pkt) if !ok { return } samples, err := rtpDec.Decode(pkt) if err != nil { log.Printf("ERR: %v", err) return } log.Printf("received G711 samples with PTS %v, size %d", pts, len(samples))})
type LPCM struct { // RTP payload type. // Static: 10 (L16 stereo 44100 Hz) or 11 (L16 mono 44100 Hz). // Dynamic: 96–127 for L8, L16, or L24 at other rates. PayloadTyp uint8 // Bit depth: 8, 16, or 24. BitDepth int // Sample rate in Hz. SampleRate int // Number of audio channels. ChannelCount int}
type AC3 struct { // RTP payload type (96–127). PayloadTyp uint8 // Sample rate in Hz. SampleRate int // Number of audio channels. Defaults to 6 if omitted in SDP. ChannelCount int}
The following formats are recognized and parsed from SDP, but do not provide CreateEncoder() or CreateDecoder() methods. You must supply your own RTP packetizer and depacketizer.
Struct
Codec
Payload type
RFC
format.Speex
Speex
dynamic (96–127)
RFC 5574
format.Vorbis
Vorbis
dynamic (96–127)
RFC 5215
format.G726
G.726
dynamic (96–127)
RFC 3551
For these formats you can still receive raw RTP packets via OnPacketRTP and implement your own framing logic:
var forma *format.Speexmedi := desc.FindFormat(&forma)if medi == nil { panic("media not found")}_, err = c.Setup(desc.BaseURL, medi, 0, 0)if err != nil { panic(err)}c.OnPacketRTP(medi, forma, func(pkt *rtp.Packet) { // pkt.Payload contains the raw Speex payload — apply your own depacketizer log.Printf("received raw Speex packet, payload size %d", len(pkt.Payload))})