mirror of
https://github.com/AlexxIT/go2rtc.git
synced 2025-10-06 16:57:29 +08:00
Support multiple codecs for WebRTC producer
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package webrtc
|
||||
|
||||
import (
|
||||
"github.com/AlexxIT/go2rtc/pkg/core"
|
||||
"github.com/AlexxIT/go2rtc/pkg/streamer"
|
||||
"github.com/pion/rtp"
|
||||
"github.com/pion/webrtc/v3"
|
||||
@@ -48,23 +49,14 @@ func (c *Conn) getProducerSendTrack(media *streamer.Media, codec *streamer.Codec
|
||||
return nil
|
||||
}
|
||||
|
||||
oldTrack := sender.Track()
|
||||
track := &Track{
|
||||
kind: media.Kind,
|
||||
payloadType: codec.PayloadType,
|
||||
|
||||
id: oldTrack.ID(),
|
||||
rid: oldTrack.RID(),
|
||||
streamID: oldTrack.StreamID(),
|
||||
}
|
||||
|
||||
if err := sender.ReplaceTrack(track); err != nil {
|
||||
track, ok := sender.Track().(*Track)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
push := func(packet *rtp.Packet) error {
|
||||
c.send += packet.MarshalSize()
|
||||
return track.WriteRTP(packet)
|
||||
return track.WriteRTP(codec.PayloadType, packet)
|
||||
}
|
||||
|
||||
return streamer.NewTrack(media, codec).Bind(push)
|
||||
@@ -82,23 +74,28 @@ func (c *Conn) getTranseiver(mid string) *webrtc.RTPTransceiver {
|
||||
type Track struct {
|
||||
kind string
|
||||
id string
|
||||
rid string
|
||||
streamID string
|
||||
payloadType byte
|
||||
sequence uint16
|
||||
ssrc uint32
|
||||
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) {
|
||||
t.ssrc = uint32(context.SSRC())
|
||||
t.writer = context.WriteStream()
|
||||
|
||||
for _, parameters := range context.CodecParameters() {
|
||||
if byte(parameters.PayloadType) == t.payloadType {
|
||||
// return first parameters
|
||||
return parameters, nil
|
||||
}
|
||||
}
|
||||
|
||||
return webrtc.RTPCodecParameters{}, nil
|
||||
}
|
||||
@@ -112,7 +109,7 @@ func (t *Track) ID() string {
|
||||
}
|
||||
|
||||
func (t *Track) RID() string {
|
||||
return t.rid
|
||||
return "" // don't know what it is
|
||||
}
|
||||
|
||||
func (t *Track) StreamID() string {
|
||||
@@ -123,13 +120,13 @@ func (t *Track) Kind() webrtc.RTPCodecType {
|
||||
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
|
||||
t.sequence++
|
||||
|
||||
header := packet.Header
|
||||
header.SSRC = t.ssrc
|
||||
header.PayloadType = t.payloadType
|
||||
header.PayloadType = payloadType
|
||||
header.SequenceNumber = t.sequence
|
||||
_, err := t.writer.WriteRTP(&header, packet.Payload)
|
||||
return err
|
||||
|
@@ -43,15 +43,18 @@ func (c *Conn) GetAnswer() (answer string, err error) {
|
||||
|
||||
for _, md := range sd.MediaDescriptions {
|
||||
for _, attr := range md.Attributes {
|
||||
var direction webrtc.RTPTransceiverDirection
|
||||
switch attr.Key {
|
||||
case "recvonly":
|
||||
_, _ = c.pc.AddTransceiverFromKind(
|
||||
webrtc.NewRTPCodecType(md.MediaName.Media),
|
||||
webrtc.RTPTransceiverInit{Direction: webrtc.RTPTransceiverDirectionSendonly},
|
||||
)
|
||||
direction = webrtc.RTPTransceiverDirectionSendonly
|
||||
case "sendrecv":
|
||||
_, _ = c.pc.AddTransceiverFromKind(
|
||||
webrtc.NewRTPCodecType(md.MediaName.Media),
|
||||
direction = webrtc.RTPTransceiverDirectionSendrecv
|
||||
}
|
||||
|
||||
if direction > 0 {
|
||||
_, _ = c.pc.AddTransceiverFromTrack(
|
||||
NewTrack(md.MediaName.Media),
|
||||
webrtc.RTPTransceiverInit{Direction: direction},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user