mirror of
https://github.com/pion/webrtc.git
synced 2025-10-26 08:40:38 +08:00
Implement SDP generation for each track
This is still a WIP, this deserves a well thought out rewrite in the future
This commit is contained in:
@@ -17,7 +17,7 @@ func (p *Port) Send(packet *rtp.Packet) {
|
||||
p.srtpContextsLock.Lock()
|
||||
srtpContext, ok := p.srtpContexts[contextMapKey]
|
||||
if !ok {
|
||||
srtpContext, err = srtp.CreateContext([]byte(authed.pair.ClientWriteKey[0:16]), []byte(authed.pair.ClientWriteKey[16:]), authed.pair.Profile, 2581832418)
|
||||
srtpContext, err = srtp.CreateContext([]byte(authed.pair.ClientWriteKey[0:16]), []byte(authed.pair.ClientWriteKey[16:]), authed.pair.Profile, packet.SSRC)
|
||||
if err != nil {
|
||||
fmt.Println("Failed to build SRTP context")
|
||||
continue
|
||||
|
||||
@@ -1,15 +1,31 @@
|
||||
package sdp
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// SessionBuilderTrack represents a single track in a SessionBuilder
|
||||
type SessionBuilderTrack struct {
|
||||
SSRC uint32
|
||||
IsAudio bool
|
||||
}
|
||||
|
||||
// SessionBuilder provides an easy way to build an SDP for an RTCPeerConnection
|
||||
type SessionBuilder struct {
|
||||
IceUsername, IcePassword, Fingerprint string
|
||||
|
||||
Candidates []string
|
||||
|
||||
Tracks []*SessionBuilderTrack
|
||||
}
|
||||
|
||||
// BaseSessionDescription generates a default SDP response that is ice-lite, initiates the DTLS session and supports VP8, VP9 and Opus
|
||||
func BaseSessionDescription(iceUsername, icePassword, fingerprint string, candidates []string) *SessionDescription {
|
||||
func BaseSessionDescription(b *SessionBuilder) *SessionDescription {
|
||||
addMediaCandidates := func(m *MediaDescription) *MediaDescription {
|
||||
m.Attributes = append(m.Attributes, candidates...)
|
||||
m.Attributes = append(m.Attributes, b.Candidates...)
|
||||
m.Attributes = append(m.Attributes, "end-of-candidates")
|
||||
return m
|
||||
}
|
||||
@@ -21,10 +37,10 @@ func BaseSessionDescription(iceUsername, icePassword, fingerprint string, candid
|
||||
"setup:active",
|
||||
"mid:audio",
|
||||
"sendrecv",
|
||||
"ice-ufrag:" + iceUsername,
|
||||
"ice-pwd:" + icePassword,
|
||||
"ice-ufrag:" + b.IceUsername,
|
||||
"ice-pwd:" + b.IcePassword,
|
||||
"ice-lite",
|
||||
"fingerprint:sha-256 " + fingerprint,
|
||||
"fingerprint:sha-256 " + b.Fingerprint,
|
||||
"rtcp-mux",
|
||||
"rtcp-rsize",
|
||||
"rtpmap:111 opus/48000/2",
|
||||
@@ -39,10 +55,10 @@ func BaseSessionDescription(iceUsername, icePassword, fingerprint string, candid
|
||||
"setup:active",
|
||||
"mid:video",
|
||||
"sendrecv",
|
||||
"ice-ufrag:" + iceUsername,
|
||||
"ice-pwd:" + icePassword,
|
||||
"ice-ufrag:" + b.IceUsername,
|
||||
"ice-pwd:" + b.IcePassword,
|
||||
"ice-lite",
|
||||
"fingerprint:sha-256 " + fingerprint,
|
||||
"fingerprint:sha-256 " + b.Fingerprint,
|
||||
"rtcp-mux",
|
||||
"rtcp-rsize",
|
||||
"rtpmap:96 VP8/90000",
|
||||
@@ -50,6 +66,26 @@ func BaseSessionDescription(iceUsername, icePassword, fingerprint string, candid
|
||||
},
|
||||
}
|
||||
|
||||
mediaStreamsAttribute := "msid-semantic: WMS"
|
||||
for i, track := range b.Tracks {
|
||||
var attributes *[]string
|
||||
if track.IsAudio {
|
||||
attributes = &audioMediaDescription.Attributes
|
||||
} else {
|
||||
attributes = &videoMediaDescription.Attributes
|
||||
}
|
||||
appendAttr := func(attr string) {
|
||||
*attributes = append(*attributes, attr)
|
||||
}
|
||||
|
||||
appendAttr("ssrc:" + fmt.Sprint(track.SSRC) + " cname:pion" + strconv.Itoa(i))
|
||||
appendAttr("ssrc:" + fmt.Sprint(track.SSRC) + " msid:pion" + strconv.Itoa(i) + " pion" + strconv.Itoa(i))
|
||||
appendAttr("ssrc:" + fmt.Sprint(track.SSRC) + " mslabel:pion" + strconv.Itoa(i))
|
||||
appendAttr("ssrc:" + fmt.Sprint(track.SSRC) + " label:pion" + strconv.Itoa(i))
|
||||
|
||||
mediaStreamsAttribute += " pion" + strconv.Itoa(i)
|
||||
}
|
||||
|
||||
sessionID := strconv.FormatUint(uint64(rand.Uint32())<<32+uint64(rand.Uint32()), 10)
|
||||
return &SessionDescription{
|
||||
ProtocolVersion: 0,
|
||||
@@ -58,7 +94,7 @@ func BaseSessionDescription(iceUsername, icePassword, fingerprint string, candid
|
||||
Timing: []string{"0 0"},
|
||||
Attributes: []string{
|
||||
"group:BUNDLE audio video",
|
||||
"msid-semantic: WMS",
|
||||
mediaStreamsAttribute,
|
||||
},
|
||||
MediaDescriptions: []*MediaDescription{
|
||||
addMediaCandidates(audioMediaDescription),
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/pions/webrtc/internal/dtls"
|
||||
"github.com/pions/webrtc/internal/network"
|
||||
@@ -11,11 +12,15 @@ import (
|
||||
"github.com/pions/webrtc/internal/util"
|
||||
"github.com/pions/webrtc/pkg/ice"
|
||||
"github.com/pions/webrtc/pkg/rtp"
|
||||
|
||||
"github.com/pions/webrtc/pkg/rtp/codecs"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func init() {
|
||||
rand.Seed(time.Now().UTC().UnixNano())
|
||||
}
|
||||
|
||||
// TrackType determines the type of media we are sending receiving
|
||||
type TrackType int
|
||||
|
||||
@@ -55,6 +60,8 @@ type RTCPeerConnection struct {
|
||||
ports []*network.Port
|
||||
|
||||
remoteDescription *sdp.SessionDescription
|
||||
|
||||
localTracks []*sdp.SessionBuilderTrack
|
||||
}
|
||||
|
||||
// Public
|
||||
@@ -96,7 +103,13 @@ func (r *RTCPeerConnection) CreateOffer() error {
|
||||
r.ports = append(r.ports, port)
|
||||
}
|
||||
|
||||
r.LocalDescription = sdp.BaseSessionDescription(r.iceUsername, r.icePassword, r.tlscfg.Fingerprint(), candidates)
|
||||
r.LocalDescription = sdp.BaseSessionDescription(&sdp.SessionBuilder{
|
||||
IceUsername: r.iceUsername,
|
||||
IcePassword: r.icePassword,
|
||||
Fingerprint: r.tlscfg.Fingerprint(),
|
||||
Candidates: candidates,
|
||||
Tracks: r.localTracks,
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -105,20 +118,26 @@ func (r *RTCPeerConnection) CreateOffer() error {
|
||||
// This function returns a channel to push buffers on, and an error if the channel can't be added
|
||||
// Closing the channel ends this stream
|
||||
func (r *RTCPeerConnection) AddTrack(mediaType TrackType) (buffers chan<- []byte, err error) {
|
||||
if mediaType != VP8 {
|
||||
panic("TODO Discarding packet, need media parsing")
|
||||
}
|
||||
|
||||
trackInput := make(chan []byte, 15)
|
||||
go func() {
|
||||
packetizer := rtp.NewPacketizer(1500, 96, 123, &codecs.VP8Payloader{}, rtp.NewRandomSequencer())
|
||||
ssrc := rand.Uint32()
|
||||
sdpTrack := &sdp.SessionBuilderTrack{SSRC: ssrc}
|
||||
if mediaType == Opus {
|
||||
sdpTrack.IsAudio = true
|
||||
}
|
||||
|
||||
r.localTracks = append(r.localTracks, sdpTrack)
|
||||
packetizer := rtp.NewPacketizer(1500, 96, ssrc, &codecs.VP8Payloader{}, rtp.NewRandomSequencer())
|
||||
for {
|
||||
if mediaType == VP8 {
|
||||
packets := packetizer.Packetize(<-trackInput)
|
||||
for _, p := range packets {
|
||||
for _, port := range r.ports {
|
||||
port.Send(p)
|
||||
}
|
||||
packets := packetizer.Packetize(<-trackInput)
|
||||
for _, p := range packets {
|
||||
for _, port := range r.ports {
|
||||
port.Send(p)
|
||||
}
|
||||
} else {
|
||||
<-trackInput
|
||||
fmt.Println("TODO Discarding packet, need media parsing")
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
Reference in New Issue
Block a user