Add support resampling for PCM for WebRTC

This commit is contained in:
Alexey Khit
2023-04-22 08:54:31 +03:00
parent fb1cc7dfc2
commit dd98edc48e
3 changed files with 178 additions and 4 deletions
+15 -4
View File
@@ -5,11 +5,12 @@ import (
"github.com/AlexxIT/go2rtc/pkg/core"
"github.com/AlexxIT/go2rtc/pkg/h264"
"github.com/AlexxIT/go2rtc/pkg/h265"
"github.com/AlexxIT/go2rtc/pkg/pcm"
"github.com/pion/rtp"
)
func (c *Conn) GetMedias() []*core.Media {
return c.medias
return WithResampling(c.medias)
}
func (c *Conn) AddTrack(media *core.Media, codec *core.Codec, track *core.Receiver) error {
@@ -31,15 +32,16 @@ func (c *Conn) AddTrack(media *core.Media, codec *core.Codec, track *core.Receiv
}
localTrack := c.getTranseiver(media.ID).Sender().Track().(*Track)
payloadType := codec.PayloadType
sender := core.NewSender(media, track.Codec)
sender := core.NewSender(media, codec)
sender.Handler = func(packet *rtp.Packet) {
c.send += packet.MarshalSize()
//important to send with remote PayloadType
_ = localTrack.WriteRTP(codec.PayloadType, packet)
_ = localTrack.WriteRTP(payloadType, packet)
}
switch codec.Name {
switch track.Codec.Name {
case core.CodecH264:
sender.Handler = h264.RTPPay(1200, sender.Handler)
if track.Codec.IsRTP() {
@@ -55,6 +57,15 @@ func (c *Conn) AddTrack(media *core.Media, codec *core.Codec, track *core.Receiv
if track.Codec.IsRTP() {
sender.Handler = h265.RTPDepay(track.Codec, sender.Handler)
}
case core.CodecPCMA, core.CodecPCMU, core.CodecPCM:
if codec.ClockRate == 0 {
if codec.Name == core.CodecPCM {
codec.Name = core.CodecPCMA
}
codec.ClockRate = 8000
sender.Handler = pcm.Resample(track.Codec, 8000, sender.Handler)
}
}
sender.HandleRTP(track)
+47
View File
@@ -52,6 +52,53 @@ func UnmarshalMedias(descriptions []*sdp.MediaDescription) (medias []*core.Media
return
}
func WithResampling(medias []*core.Media) []*core.Media {
for _, media := range medias {
if media.Kind != core.KindAudio || media.Direction != core.DirectionSendonly {
continue
}
var pcma, pcmu, pcm *core.Codec
for _, codec := range media.Codecs {
switch codec.Name {
case core.CodecPCMA:
if codec.ClockRate != 0 {
pcma = codec
} else {
pcma = nil
}
case core.CodecPCMU:
if codec.ClockRate != 0 {
pcmu = codec
} else {
pcmu = nil
}
case core.CodecPCM:
pcm = codec
}
}
if pcma != nil {
pcma = pcma.Clone()
pcma.ClockRate = 0 // reset clock rate so will match any
media.Codecs = append(media.Codecs, pcma)
}
if pcmu != nil {
pcmu = pcmu.Clone()
pcmu.ClockRate = 0
media.Codecs = append(media.Codecs, pcmu)
}
if pcma != nil && pcm == nil {
pcm = pcma.Clone()
pcm.Name = core.CodecPCM
media.Codecs = append(media.Codecs, pcm)
}
}
return medias
}
func NewCandidate(network, address string) (string, error) {
i := strings.LastIndexByte(address, ':')
if i < 0 {