Support multiple codecs for WebRTC producer

This commit is contained in:
Alexey Khit
2023-03-12 14:30:42 +03:00
parent 0b714a59e5
commit 0382fbf8a9
2 changed files with 32 additions and 32 deletions

View File

@@ -1,6 +1,7 @@
package webrtc package webrtc
import ( import (
"github.com/AlexxIT/go2rtc/pkg/core"
"github.com/AlexxIT/go2rtc/pkg/streamer" "github.com/AlexxIT/go2rtc/pkg/streamer"
"github.com/pion/rtp" "github.com/pion/rtp"
"github.com/pion/webrtc/v3" "github.com/pion/webrtc/v3"
@@ -48,23 +49,14 @@ func (c *Conn) getProducerSendTrack(media *streamer.Media, codec *streamer.Codec
return nil return nil
} }
oldTrack := sender.Track() track, ok := sender.Track().(*Track)
track := &Track{ if !ok {
kind: media.Kind,
payloadType: codec.PayloadType,
id: oldTrack.ID(),
rid: oldTrack.RID(),
streamID: oldTrack.StreamID(),
}
if err := sender.ReplaceTrack(track); err != nil {
return nil return nil
} }
push := func(packet *rtp.Packet) error { push := func(packet *rtp.Packet) error {
c.send += packet.MarshalSize() c.send += packet.MarshalSize()
return track.WriteRTP(packet) return track.WriteRTP(codec.PayloadType, packet)
} }
return streamer.NewTrack(media, codec).Bind(push) return streamer.NewTrack(media, codec).Bind(push)
@@ -82,23 +74,28 @@ func (c *Conn) getTranseiver(mid string) *webrtc.RTPTransceiver {
type Track struct { type Track struct {
kind string kind string
id string id string
rid string
streamID string streamID string
payloadType byte
sequence uint16 sequence uint16
ssrc uint32 ssrc uint32
writer webrtc.TrackLocalWriter writer webrtc.TrackLocalWriter
} }
func NewTrack(kind string) *Track {
return &Track{
kind: kind,
id: core.RandString(16),
streamID: core.RandString(16),
}
}
func (t *Track) Bind(context webrtc.TrackLocalContext) (webrtc.RTPCodecParameters, error) { func (t *Track) Bind(context webrtc.TrackLocalContext) (webrtc.RTPCodecParameters, error) {
t.ssrc = uint32(context.SSRC()) t.ssrc = uint32(context.SSRC())
t.writer = context.WriteStream() t.writer = context.WriteStream()
for _, parameters := range context.CodecParameters() { for _, parameters := range context.CodecParameters() {
if byte(parameters.PayloadType) == t.payloadType { // return first parameters
return parameters, nil return parameters, nil
} }
}
return webrtc.RTPCodecParameters{}, nil return webrtc.RTPCodecParameters{}, nil
} }
@@ -112,7 +109,7 @@ func (t *Track) ID() string {
} }
func (t *Track) RID() string { func (t *Track) RID() string {
return t.rid return "" // don't know what it is
} }
func (t *Track) StreamID() string { func (t *Track) StreamID() string {
@@ -123,13 +120,13 @@ func (t *Track) Kind() webrtc.RTPCodecType {
return webrtc.NewRTPCodecType(t.kind) return webrtc.NewRTPCodecType(t.kind)
} }
func (t *Track) WriteRTP(packet *rtp.Packet) error { func (t *Track) WriteRTP(payloadType uint8, packet *rtp.Packet) error {
// important to have internal counter if input packets from different sources // important to have internal counter if input packets from different sources
t.sequence++ t.sequence++
header := packet.Header header := packet.Header
header.SSRC = t.ssrc header.SSRC = t.ssrc
header.PayloadType = t.payloadType header.PayloadType = payloadType
header.SequenceNumber = t.sequence header.SequenceNumber = t.sequence
_, err := t.writer.WriteRTP(&header, packet.Payload) _, err := t.writer.WriteRTP(&header, packet.Payload)
return err return err

View File

@@ -43,15 +43,18 @@ func (c *Conn) GetAnswer() (answer string, err error) {
for _, md := range sd.MediaDescriptions { for _, md := range sd.MediaDescriptions {
for _, attr := range md.Attributes { for _, attr := range md.Attributes {
var direction webrtc.RTPTransceiverDirection
switch attr.Key { switch attr.Key {
case "recvonly": case "recvonly":
_, _ = c.pc.AddTransceiverFromKind( direction = webrtc.RTPTransceiverDirectionSendonly
webrtc.NewRTPCodecType(md.MediaName.Media),
webrtc.RTPTransceiverInit{Direction: webrtc.RTPTransceiverDirectionSendonly},
)
case "sendrecv": case "sendrecv":
_, _ = c.pc.AddTransceiverFromKind( direction = webrtc.RTPTransceiverDirectionSendrecv
webrtc.NewRTPCodecType(md.MediaName.Media), }
if direction > 0 {
_, _ = c.pc.AddTransceiverFromTrack(
NewTrack(md.MediaName.Media),
webrtc.RTPTransceiverInit{Direction: direction},
) )
} }
} }