Files
gortsplib/track_opus.go
2021-10-30 15:45:13 +02:00

94 lines
1.9 KiB
Go

package gortsplib
import (
"fmt"
"strconv"
"strings"
psdp "github.com/pion/sdp/v3"
)
// TrackConfigOpus is the configuration of an Opus track.
type TrackConfigOpus struct {
SampleRate int
ChannelCount int
}
// NewTrackOpus initializes an Opus track.
func NewTrackOpus(payloadType uint8, conf *TrackConfigOpus) (*Track, error) {
typ := strconv.FormatInt(int64(payloadType), 10)
return &Track{
Media: &psdp.MediaDescription{
MediaName: psdp.MediaName{
Media: "audio",
Protos: []string{"RTP", "AVP"},
Formats: []string{typ},
},
Attributes: []psdp.Attribute{
{
Key: "rtpmap",
Value: typ + " opus/" + strconv.FormatInt(int64(conf.SampleRate), 10) +
"/" + strconv.FormatInt(int64(conf.ChannelCount), 10),
},
{
Key: "fmtp",
Value: typ + " sprop-stereo=" + func() string {
if conf.ChannelCount == 2 {
return "1"
}
return "0"
}(),
},
},
},
}, nil
}
// IsOpus checks whether the track is an Opus track.
func (t *Track) IsOpus() bool {
if t.Media.MediaName.Media != "audio" {
return false
}
v, ok := t.Media.Attribute("rtpmap")
if !ok {
return false
}
vals := strings.Split(v, " ")
if len(vals) != 2 {
return false
}
return strings.HasPrefix(vals[1], "opus/")
}
// ExtractConfigOpus extracts the configuration of an Opus track.
func (t *Track) ExtractConfigOpus() (*TrackConfigOpus, error) {
v, ok := t.Media.Attribute("rtpmap")
if !ok {
return nil, fmt.Errorf("rtpmap attribute is missing")
}
tmp := strings.SplitN(v, "/", 3)
if len(tmp) != 3 {
return nil, fmt.Errorf("invalid rtpmap (%v)", v)
}
sampleRate, err := strconv.ParseInt(tmp[1], 10, 64)
if err != nil {
return nil, err
}
channelCount, err := strconv.ParseInt(tmp[2], 10, 64)
if err != nil {
return nil, err
}
return &TrackConfigOpus{
SampleRate: int(sampleRate),
ChannelCount: int(channelCount),
}, nil
}