mirror of
https://github.com/livekit/livekit.git
synced 2026-05-18 13:26:11 +00:00
use protocol/sdp for sdp process (#926)
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user