use protocol/sdp for sdp process (#926)

This commit is contained in:
cnderrauber
2022-08-17 16:12:33 +08:00
committed by GitHub
parent df78179bbb
commit f819dcb63d
3 changed files with 8 additions and 123 deletions
+1 -1
View File
@@ -16,7 +16,7 @@ require (
github.com/gorilla/websocket v1.5.0
github.com/hashicorp/go-version v1.6.0
github.com/hashicorp/golang-lru v0.5.4
github.com/livekit/protocol v1.0.1
github.com/livekit/protocol v1.0.2-0.20220817073830-613285ea6f32
github.com/livekit/rtcscore-go v0.0.0-20220815072451-20ee10ae1995
github.com/mackerelio/go-osstat v0.2.2
github.com/magefile/mage v1.13.0
+2 -2
View File
@@ -240,8 +240,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/lithammer/shortuuid/v3 v3.0.7 h1:trX0KTHy4Pbwo/6ia8fscyHoGA+mf1jWbPJVuvyJQQ8=
github.com/lithammer/shortuuid/v3 v3.0.7/go.mod h1:vMk8ke37EmiewwolSO1NLW8vP4ZaKlRuDIi8tWWmAts=
github.com/livekit/protocol v1.0.1 h1:WgJyGPijoBeZInVhPWQfPYEIjRKkDKMaOQU1IX1co08=
github.com/livekit/protocol v1.0.1/go.mod h1:hN0rI0/QsnGXp3oYnFktdquU3FPetAl8/naweFo6oPs=
github.com/livekit/protocol v1.0.2-0.20220817073830-613285ea6f32 h1:S0qziW4Bh8k2DM2PYMk0O8RnsLdqUMhUA6G4vhg+KE4=
github.com/livekit/protocol v1.0.2-0.20220817073830-613285ea6f32/go.mod h1:qTrokXCWMngkI7tszAlNXaSsNjkVrKmSuBz2AXABt8s=
github.com/livekit/rtcscore-go v0.0.0-20220815072451-20ee10ae1995 h1:vOaY2qvfLihDyeZtnGGN1Law9wRrw8BMGCr1TygTvMw=
github.com/livekit/rtcscore-go v0.0.0-20220815072451-20ee10ae1995/go.mod h1:116ych8UaEs9vfIE8n6iZCZ30iagUFTls0vRmC+Ix5U=
github.com/mackerelio/go-osstat v0.2.2 h1:7jVyXGXTkQL3+6lDVUDBY+Fpo8VQPfyOkZeXxxsXX4c=
+5 -120
View File
@@ -21,6 +21,7 @@ import (
"github.com/livekit/protocol/livekit"
"github.com/livekit/protocol/logger"
lksdp "github.com/livekit/protocol/sdp"
"github.com/livekit/livekit-server/pkg/config"
serverlogger "github.com/livekit/livekit-server/pkg/logger"
@@ -771,7 +772,7 @@ func (t *PCTransport) isRemoteOfferRestartICE(sd webrtc.SessionDescription) (str
if err != nil {
return "", false, err
}
user, pwd, err := extractICECredential(parsed)
user, pwd, err := lksdp.ExtractICECredential(parsed)
if err != nil {
return "", false, err
}
@@ -1119,7 +1120,7 @@ func (t *PCTransport) preparePC(previousAnswer webrtc.SessionDescription) error
if err != nil {
return err
}
fp, fpHahs, err := extractFingerprint(parsed)
fp, fpHahs, err := lksdp.ExtractFingerprint(parsed)
if err != nil {
return err
}
@@ -1137,7 +1138,7 @@ func (t *PCTransport) preparePC(previousAnswer webrtc.SessionDescription) error
// trying to replicate previous setup, read from previous answer and use that role.
//
se := webrtc.SettingEngine{}
se.SetAnsweringDTLSRole(extractDTLSRole(parsed))
se.SetAnsweringDTLSRole(lksdp.ExtractDTLSRole(parsed))
api := webrtc.NewAPI(
webrtc.WithSettingEngine(se),
webrtc.WithMediaEngine(t.me),
@@ -1214,7 +1215,7 @@ func (t *PCTransport) initPCWithPreviousAnswer(previousAnswer webrtc.SessionDesc
return err
}
tr.Stop()
mid := getMidValue(m)
mid := lksdp.GetMidValue(m)
if mid == "" {
return errors.New("mid value not found")
}
@@ -1301,119 +1302,3 @@ func (t *PCTransport) filterCandidates(sd webrtc.SessionDescription) webrtc.Sess
sd.SDP = string(bytes)
return sd
}
// ---------------------------------------------
func getMidValue(media *sdp.MediaDescription) string {
for _, attr := range media.Attributes {
if attr.Key == sdp.AttrKeyMID {
return attr.Value
}
}
return ""
}
func extractFingerprint(desc *sdp.SessionDescription) (string, string, error) {
fingerprints := make([]string, 0)
if fingerprint, haveFingerprint := desc.Attribute("fingerprint"); haveFingerprint {
fingerprints = append(fingerprints, fingerprint)
}
for _, m := range desc.MediaDescriptions {
if fingerprint, haveFingerprint := m.Attribute("fingerprint"); haveFingerprint {
fingerprints = append(fingerprints, fingerprint)
}
}
if len(fingerprints) < 1 {
return "", "", webrtc.ErrSessionDescriptionNoFingerprint
}
for _, m := range fingerprints {
if m != fingerprints[0] {
return "", "", webrtc.ErrSessionDescriptionConflictingFingerprints
}
}
parts := strings.Split(fingerprints[0], " ")
if len(parts) != 2 {
return "", "", webrtc.ErrSessionDescriptionInvalidFingerprint
}
return parts[1], parts[0], nil
}
func extractDTLSRole(desc *sdp.SessionDescription) webrtc.DTLSRole {
for _, md := range desc.MediaDescriptions {
setup, ok := md.Attribute(sdp.AttrKeyConnectionSetup)
if !ok {
continue
}
if setup == sdp.ConnectionRoleActive.String() {
return webrtc.DTLSRoleClient
}
if setup == sdp.ConnectionRolePassive.String() {
return webrtc.DTLSRoleServer
}
}
//
// If 'setup' attribute is not available, use client role
// as that is the default behaviour of answerers
//
// There seems to be some differences in how role is decided.
// libwebrtc (Chrome) code - (https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/pc/jsep_transport.cc;l=592;drc=369fb686729e7eb20d2bd09717cec14269a399d7)
// does not mention anything about ICE role when determining
// DTLS Role.
//
// But, ORTC has this - https://github.com/w3c/ortc/issues/167#issuecomment-69409953
// and pion/webrtc follows that (https://github.com/pion/webrtc/blob/e071a4eded1efd5d9b401bcfc4efacb3a2a5a53c/dtlstransport.go#L269)
//
// So if remote is ice-lite, pion will use DTLSRoleServer when answering
// while browsers pick DTLSRoleClient.
//
return webrtc.DTLSRoleClient
}
func extractICECredential(desc *sdp.SessionDescription) (string, string, error) {
remotePwds := []string{}
remoteUfrags := []string{}
if ufrag, haveUfrag := desc.Attribute("ice-ufrag"); haveUfrag {
remoteUfrags = append(remoteUfrags, ufrag)
}
if pwd, havePwd := desc.Attribute("ice-pwd"); havePwd {
remotePwds = append(remotePwds, pwd)
}
for _, m := range desc.MediaDescriptions {
if ufrag, haveUfrag := m.Attribute("ice-ufrag"); haveUfrag {
remoteUfrags = append(remoteUfrags, ufrag)
}
if pwd, havePwd := m.Attribute("ice-pwd"); havePwd {
remotePwds = append(remotePwds, pwd)
}
}
if len(remoteUfrags) == 0 {
return "", "", webrtc.ErrSessionDescriptionMissingIceUfrag
} else if len(remotePwds) == 0 {
return "", "", webrtc.ErrSessionDescriptionMissingIcePwd
}
for _, m := range remoteUfrags {
if m != remoteUfrags[0] {
return "", "", webrtc.ErrSessionDescriptionConflictingIceUfrag
}
}
for _, m := range remotePwds {
if m != remotePwds[0] {
return "", "", webrtc.ErrSessionDescriptionConflictingIcePwd
}
}
return remoteUfrags[0], remotePwds[0], nil
}