mirror of
https://github.com/AlexxIT/go2rtc.git
synced 2025-10-07 01:03:07 +08:00
Support multiple codecs for WebRTC producer
This commit is contained in:
@@ -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)
|
||||||
@@ -80,14 +72,20 @@ 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
|
sequence uint16
|
||||||
payloadType byte
|
ssrc uint32
|
||||||
sequence uint16
|
writer webrtc.TrackLocalWriter
|
||||||
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) {
|
func (t *Track) Bind(context webrtc.TrackLocalContext) (webrtc.RTPCodecParameters, error) {
|
||||||
@@ -95,9 +93,8 @@ func (t *Track) Bind(context webrtc.TrackLocalContext) (webrtc.RTPCodecParameter
|
|||||||
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
|
||||||
|
@@ -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},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user