diff --git a/conn/conn.go b/conn/conn.go index 45ccf9f..1e95fef 100644 --- a/conn/conn.go +++ b/conn/conn.go @@ -29,7 +29,7 @@ type UpTrack interface { AddLocal(DownTrack) error DelLocal(DownTrack) bool Label() string - Codec() *webrtc.RTPCodec + Codec() webrtc.RTPCodecCapability // get a recent packet. Returns 0 if the packet is not in cache. GetRTP(seqno uint16, result []byte) uint16 Nack(conn Up, seqnos []uint16) error diff --git a/diskwriter/diskwriter.go b/diskwriter/diskwriter.go index 986a986..fb7ab12 100644 --- a/diskwriter/diskwriter.go +++ b/diskwriter/diskwriter.go @@ -7,13 +7,13 @@ import ( "fmt" "os" "path/filepath" + "strings" "sync" "time" "github.com/at-wat/ebml-go/webm" "github.com/pion/rtp" "github.com/pion/rtp/codecs" - "github.com/pion/webrtc/v3" "github.com/pion/webrtc/v3/pkg/media/samplebuilder" "sfu/conn" @@ -227,20 +227,21 @@ func newDiskConn(directory, label string, up conn.Up, remoteTracks []conn.UpTrac } for _, remote := range remoteTracks { var builder *samplebuilder.SampleBuilder - switch remote.Codec().Name { - case webrtc.Opus: + codec := remote.Codec() + switch strings.ToLower(codec.MimeType) { + case "audio/opus": builder = samplebuilder.New( - 16, &codecs.OpusPacket{}, + 16, &codecs.OpusPacket{}, codec.ClockRate, samplebuilder.WithPartitionHeadChecker( &codecs.OpusPartitionHeadChecker{}, ), ) - case webrtc.VP8: + case "video/vp8": if conn.hasVideo { return nil, errors.New("multiple video tracks not supported") } builder = samplebuilder.New( - 128, &codecs.VP8Packet{}, + 128, &codecs.VP8Packet{}, codec.ClockRate, samplebuilder.WithPartitionHeadChecker( &codecs.VP8PartitionHeadChecker{}, ), @@ -312,8 +313,9 @@ func (t *diskTrack) WriteRTP(packet *rtp.Packet) error { keyframe := true - switch t.remote.Codec().Name { - case webrtc.VP8: + codec := t.remote.Codec() + switch strings.ToLower(codec.MimeType) { + case "video/vp8": if len(sample.Data) < 1 { continue } @@ -365,8 +367,9 @@ func (t *diskTrack) WriteRTP(packet *rtp.Packet) error { // called locked func (t *diskTrack) initWriter(data []byte) error { - switch t.remote.Codec().Name { - case webrtc.VP8: + codec := t.remote.Codec() + switch strings.ToLower(codec.MimeType) { + case "video/vp8": if len(data) < 10 { return nil } @@ -390,10 +393,10 @@ func (conn *diskConn) initWriter(width, height uint32) error { } var entries []webm.TrackEntry for i, t := range conn.tracks { - codec := t.remote.Codec() var entry webm.TrackEntry - switch t.remote.Codec().Name { - case webrtc.Opus: + codec := t.remote.Codec() + switch strings.ToLower(codec.MimeType) { + case "audio/opus": entry = webm.TrackEntry{ Name: "Audio", TrackNumber: uint64(i + 1), @@ -404,7 +407,7 @@ func (conn *diskConn) initWriter(width, height uint32) error { Channels: uint64(codec.Channels), }, } - case webrtc.VP8: + case "video/vp8": entry = webm.TrackEntry{ Name: "Video", TrackNumber: uint64(i + 1), diff --git a/go.mod b/go.mod index 036c97b..0b4c74c 100644 --- a/go.mod +++ b/go.mod @@ -5,9 +5,9 @@ go 1.13 require ( github.com/at-wat/ebml-go v0.11.0 github.com/gorilla/websocket v1.4.2 - github.com/pion/ice/v2 v2.0.7 - github.com/pion/rtcp v1.2.5 + github.com/pion/ice/v2 v2.0.13 + github.com/pion/rtcp v1.2.6 github.com/pion/rtp v1.6.1 - github.com/pion/webrtc/v3 v3.0.0-beta.7 - golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a + github.com/pion/webrtc/v3 v3.0.0-beta.15 + golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 ) diff --git a/go.sum b/go.sum index 0cfaa93..5d56396 100644 --- a/go.sum +++ b/go.sum @@ -110,10 +110,12 @@ github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1y github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= github.com/pion/datachannel v1.4.21 h1:3ZvhNyfmxsAqltQrApLPQMhSFNA+aT87RqyCq4OXmf0= github.com/pion/datachannel v1.4.21/go.mod h1:oiNyP4gHx2DIwRzX/MFyH0Rz/Gz05OgBlayAI2hAWjg= -github.com/pion/dtls/v2 v2.0.3 h1:3qQ0s4+TXD00rsllL8g8KQcxAs+Y/Z6oz618RXX6p14= -github.com/pion/dtls/v2 v2.0.3/go.mod h1:TUjyL8bf8LH95h81Xj7kATmzMRt29F/4lxpIPj2Xe4Y= -github.com/pion/ice/v2 v2.0.7 h1:3Iv+EfthCdPbJCsPbhnL4xRzolR1oh9mJTuUsxyxPJI= -github.com/pion/ice/v2 v2.0.7/go.mod h1:0C4VBZxkO3A7Qj5ZEgZut8OptbJFSbuGNyPyJMftuHA= +github.com/pion/dtls/v2 v2.0.4 h1:WuUcqi6oYMu/noNTz92QrF1DaFj4eXbhQ6dzaaAwOiI= +github.com/pion/dtls/v2 v2.0.4/go.mod h1:qAkFscX0ZHoI1E07RfYPoRw3manThveu+mlTDdOxoGI= +github.com/pion/ice/v2 v2.0.13 h1:lVe7g86tQ0vKdH430hQR/t7zV1oeXbK75130TUArrnw= +github.com/pion/ice/v2 v2.0.13/go.mod h1:mZlypgoynMn2ayhGsjrPY/G/WiRiYO8WCPC6gUeg1RA= +github.com/pion/interceptor v0.0.5 h1:BOwlubM1lntji3eNaVrhW1Qk3u1UoemrhM4mbv24XGM= +github.com/pion/interceptor v0.0.5/go.mod h1:lPVrf5xfosI989ZcmgPS4WwwRhd+XAyTFaYI2wHf7nU= github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms= github.com/pion/mdns v0.0.4 h1:O4vvVqr4DGX63vzmO6Fw9vpy3lfztVWHGCQfyw0ZLSY= @@ -124,17 +126,17 @@ github.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA= github.com/pion/randutil v0.1.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8= github.com/pion/rtcp v1.2.4 h1:NT3H5LkUGgaEapvp0HGik+a+CpflRF7KTD7H+o7OWIM= github.com/pion/rtcp v1.2.4/go.mod h1:52rMNPWFsjr39z9B9MhnkqhPLoeHTv1aN63o/42bWE0= -github.com/pion/rtcp v1.2.5 h1:CbZu6JujwnFUkvpJHh/0ypzKla45KX3nPnvXBe4P0hQ= -github.com/pion/rtcp v1.2.5/go.mod h1:52rMNPWFsjr39z9B9MhnkqhPLoeHTv1aN63o/42bWE0= +github.com/pion/rtcp v1.2.6 h1:1zvwBbyd0TeEuuWftrd/4d++m+/kZSeiguxU61LFWpo= +github.com/pion/rtcp v1.2.6/go.mod h1:52rMNPWFsjr39z9B9MhnkqhPLoeHTv1aN63o/42bWE0= github.com/pion/rtp v1.6.1 h1:2Y2elcVBrahYnHKN2X7rMHX/r1R4TEBMP1LaVu/wNhk= github.com/pion/rtp v1.6.1/go.mod h1:bDb5n+BFZxXx0Ea7E5qe+klMuqiBrP+w8XSjiWtCUko= github.com/pion/sctp v1.7.10/go.mod h1:EhpTUQu1/lcK3xI+eriS6/96fWetHGCvBi9MSsnaBN0= github.com/pion/sctp v1.7.11 h1:UCnj7MsobLKLuP/Hh+JMiI/6W5Bs/VF45lWKgHFjSIE= github.com/pion/sctp v1.7.11/go.mod h1:EhpTUQu1/lcK3xI+eriS6/96fWetHGCvBi9MSsnaBN0= -github.com/pion/sdp/v3 v3.0.2 h1:UNnSPVaMM+Pdu/mR9UvAyyo6zkdYbKeuOooCwZvTl/g= -github.com/pion/sdp/v3 v3.0.2/go.mod h1:bNiSknmJE0HYBprTHXKPQ3+JjacTv5uap92ueJZKsRk= -github.com/pion/srtp v1.5.2 h1:25DmvH+fqKZDqvX64vTwnycVwL9ooJxHF/gkX16bDBY= -github.com/pion/srtp v1.5.2/go.mod h1:NiBff/MSxUwMUwx/fRNyD/xGE+dVvf8BOCeXhjCXZ9U= +github.com/pion/sdp/v3 v3.0.3 h1:gJK9hk+JFD2NGIM1nXmqNCq1DkVaIZ9dlA3u3otnkaw= +github.com/pion/sdp/v3 v3.0.3/go.mod h1:bNiSknmJE0HYBprTHXKPQ3+JjacTv5uap92ueJZKsRk= +github.com/pion/srtp/v2 v2.0.0-rc.3 h1:1fPiK1nJlNyh235tSGgBnXrPc99wK1/D707f6ntb3qY= +github.com/pion/srtp/v2 v2.0.0-rc.3/go.mod h1:S6J9oY6ahAXdU3ni4nUwhWTJuBfssFjPxoB0u41TBpY= github.com/pion/stun v0.3.5 h1:uLUCBCkQby4S1cf6CGuR9QrVOKcvUwFeemaC865QHDg= github.com/pion/stun v0.3.5/go.mod h1:gDMim+47EeEtfWogA37n6qXZS88L5V6LqFcf+DZA2UA= github.com/pion/transport v0.8.10/go.mod h1:tBmha/UCjpum5hqTWhfAEs3CO4/tHSg0MYRhSzR+CZ8= @@ -142,12 +144,16 @@ github.com/pion/transport v0.10.0 h1:9M12BSneJm6ggGhJyWpDveFOstJsTiQjkLf4M44rm80 github.com/pion/transport v0.10.0/go.mod h1:BnHnUipd0rZQyTVB2SBGojFHT9CBt5C5TcsJSQGkvSE= github.com/pion/transport v0.10.1 h1:2W+yJT+0mOQ160ThZYUx5Zp2skzshiNgxrNE9GUfhJM= github.com/pion/transport v0.10.1/go.mod h1:PBis1stIILMiis0PewDw91WJeLJkyIMcEk+DwKOzf4A= -github.com/pion/turn/v2 v2.0.4 h1:oDguhEv2L/4rxwbL9clGLgtzQPjtuZwCdoM7Te8vQVk= -github.com/pion/turn/v2 v2.0.4/go.mod h1:1812p4DcGVbYVBTiraUmP50XoKye++AMkbfp+N27mog= +github.com/pion/transport v0.11.0 h1:Z1RhzqrWPPYj5Xed8P7pirTKTvXFoxDI3uJuuKu6akM= +github.com/pion/transport v0.11.0/go.mod h1:ORH8Ouyl1enoJyHwU+MwMeQocWbeorEk5068FOsHjog= +github.com/pion/transport v0.12.0 h1:UFmOBBZkTZ3LgvLRf/NGrfWdZEubcU6zkLU3PsA9YvU= +github.com/pion/transport v0.12.0/go.mod h1:N3+vZQD9HlDP5GWkZ85LohxNsDcNgofQmyL6ojX5d8Q= +github.com/pion/turn/v2 v2.0.5 h1:iwMHqDfPEDEOFzwWKT56eFmh6DYC6o/+xnLAEzgISbA= +github.com/pion/turn/v2 v2.0.5/go.mod h1:APg43CFyt/14Uy7heYUOGWdkem/Wu4PhCO/bjyrTqMw= github.com/pion/udp v0.1.0 h1:uGxQsNyrqG3GLINv36Ff60covYmfrLoxzwnCsIYspXI= github.com/pion/udp v0.1.0/go.mod h1:BPELIjbwE9PRbd/zxI/KYBnbo7B6+oA6YuEaNE8lths= -github.com/pion/webrtc/v3 v3.0.0-beta.7 h1:wDzex7YkT3wErRGaW4yOs9ziCQeuVF04poWVTqQ8o/Q= -github.com/pion/webrtc/v3 v3.0.0-beta.7/go.mod h1:g2FHuaaKKuoZ9RlKIDAYvnO/rhocYG/d+2Ly1hRa85o= +github.com/pion/webrtc/v3 v3.0.0-beta.15 h1:Toh2b7di3TGO6X3aAhecW4YP4jfrXITmcq0vb2k5H8o= +github.com/pion/webrtc/v3 v3.0.0-beta.15/go.mod h1:3ddDqLYD6D/dU+YAUoaAiPiSTH7hwf72qDITE5hMPf4= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -204,8 +210,8 @@ golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a h1:vclmkQCjlDX5OydZ9wv8rBCcS0QyQY66Mpf/7BZbInM= -golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 h1:pLI5jrR7OSLijeIDcmRxNmw2api+jEfxLoykJVice/E= +golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -229,8 +235,9 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344 h1:vGXIOMxbNfDTk/aXCmfdLgkrS golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA= -golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201201195509-5d6afe98e0b7 h1:3uJsdck53FDIpWwLeAXlia9p4C8j0BO2xZrqzKpL0D8= +golang.org/x/net v0.0.0-20201201195509-5d6afe98e0b7/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -259,12 +266,16 @@ golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20u golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299 h1:DYfZAGf2WMFjMxbgTjaC+2HC7NkNAQs+6Q8b9WEB/F4= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/group/group.go b/group/group.go index dcf1e27..39178c0 100644 --- a/group/group.go +++ b/group/group.go @@ -174,22 +174,36 @@ func Add(name string, desc *description) (*Group, error) { s.SetICEMulticastDNSMode(ice.MulticastDNSModeDisabled) } m := webrtc.MediaEngine{} - m.RegisterCodec(webrtc.NewRTPVP8CodecExt( - webrtc.DefaultPayloadTypeVP8, 90000, - []webrtc.RTCPFeedback{ - {"goog-remb", ""}, - {"nack", ""}, - {"nack", "pli"}, - {"ccm", "fir"}, + m.RegisterCodec( + webrtc.RTPCodecParameters{ + RTPCodecCapability: webrtc.RTPCodecCapability{ + "video/VP8", 90000, 0, + "", + []webrtc.RTCPFeedback{ + {"goog-remb", ""}, + {"nack", ""}, + {"nack", "pli"}, + {"ccm", "fir"}, + }, + }, + PayloadType: 96, }, - "", - )) - m.RegisterCodec(webrtc.NewRTPOpusCodec( - webrtc.DefaultPayloadTypeOpus, 48000, - )) + webrtc.RTPCodecTypeVideo, + ) + m.RegisterCodec( + webrtc.RTPCodecParameters{ + RTPCodecCapability: webrtc.RTPCodecCapability{ + "audio/opus", 48000, 2, + "minptime=10;useinbandfec=1", + nil, + }, + PayloadType: 111, + }, + webrtc.RTPCodecTypeAudio, + ) groups.api = webrtc.NewAPI( webrtc.WithSettingEngine(s), - webrtc.WithMediaEngine(m), + webrtc.WithMediaEngine(&m), ) } diff --git a/rtpconn/rtpconn.go b/rtpconn/rtpconn.go index 338e6c2..1c8f00b 100644 --- a/rtpconn/rtpconn.go +++ b/rtpconn/rtpconn.go @@ -67,8 +67,9 @@ type iceConnection interface { } type rtpDownTrack struct { - track *webrtc.Track + track *webrtc.TrackLocalStaticRTP remote conn.UpTrack + ssrc webrtc.SSRC maxBitrate *bitrate rate *estimator.Estimator stats *receiverStats @@ -112,7 +113,7 @@ func newDownConn(c group.Client, id string, remote conn.Up) (*rtpDownConnection, return nil, err } - pc.OnTrack(func(remote *webrtc.Track, receiver *webrtc.RTPReceiver) { + pc.OnTrack(func(remote *webrtc.TrackRemote, receiver *webrtc.RTPReceiver) { log.Printf("Got track on downstream connection") }) @@ -176,7 +177,7 @@ func (down *rtpDownConnection) flushICECandidates() error { } type rtpUpTrack struct { - track *webrtc.Track + track *webrtc.TrackRemote label string rate *estimator.Estimator cache *packetcache.Cache @@ -257,8 +258,8 @@ func (up *rtpUpTrack) Label() string { return up.label } -func (up *rtpUpTrack) Codec() *webrtc.RTPCodec { - return up.track.Codec() +func (up *rtpUpTrack) Codec() webrtc.RTPCodecCapability { + return up.track.Codec().RTPCodecCapability } func (up *rtpUpTrack) hasRtcpFb(tpe, parameter string) bool { @@ -344,7 +345,7 @@ func (up *rtpUpConnection) flushICECandidates() error { return err } -func getTrackMid(pc *webrtc.PeerConnection, track *webrtc.Track) string { +func getTrackMid(pc *webrtc.PeerConnection, track *webrtc.TrackRemote) string { for _, t := range pc.GetTransceivers() { if t.Receiver() != nil && t.Receiver().Track() == track { return t.Mid() @@ -399,7 +400,7 @@ func newUpConn(c group.Client, id string) (*rtpUpConnection, error) { up := &rtpUpConnection{id: id, pc: pc} - pc.OnTrack(func(remote *webrtc.Track, receiver *webrtc.RTPReceiver) { + pc.OnTrack(func(remote *webrtc.TrackRemote, receiver *webrtc.RTPReceiver) { up.mu.Lock() mid := getTrackMid(pc, remote) @@ -475,9 +476,9 @@ func (up *rtpUpConnection) sendPLI(track *rtpUpTrack) error { return sendPLI(up.pc, track.track.SSRC()) } -func sendPLI(pc *webrtc.PeerConnection, ssrc uint32) error { +func sendPLI(pc *webrtc.PeerConnection, ssrc webrtc.SSRC) error { return pc.WriteRTCP([]rtcp.Packet{ - &rtcp.PictureLossIndication{MediaSSRC: ssrc}, + &rtcp.PictureLossIndication{MediaSSRC: uint32(ssrc)}, }) } @@ -503,12 +504,12 @@ func (up *rtpUpConnection) sendFIR(track *rtpUpTrack, increment bool) error { return sendFIR(up.pc, track.track.SSRC(), seqno) } -func sendFIR(pc *webrtc.PeerConnection, ssrc uint32, seqno uint8) error { +func sendFIR(pc *webrtc.PeerConnection, ssrc webrtc.SSRC, seqno uint8) error { return pc.WriteRTCP([]rtcp.Packet{ &rtcp.FullIntraRequest{ FIR: []rtcp.FIREntry{ { - SSRC: ssrc, + SSRC: uint32(ssrc), SequenceNumber: seqno, }, }, @@ -558,10 +559,10 @@ func (up *rtpUpConnection) sendNACKs(track *rtpUpTrack, seqnos []uint16) error { return err } -func sendNACKs(pc *webrtc.PeerConnection, ssrc uint32, nacks []rtcp.NackPair) error { +func sendNACKs(pc *webrtc.PeerConnection, ssrc webrtc.SSRC, nacks []rtcp.NackPair) error { packet := rtcp.Packet( &rtcp.TransportLayerNack{ - MediaSSRC: ssrc, + MediaSSRC: uint32(ssrc), Nacks: nacks, }, ) @@ -663,7 +664,7 @@ func rtcpUpListener(conn *rtpUpConnection, track *rtpUpTrack, r *webrtc.RTPRecei } case *rtcp.SourceDescription: for _, c := range p.Chunks { - if c.Source != track.track.SSRC() { + if c.Source != uint32(track.track.SSRC()) { continue } for _, i := range c.Items { @@ -735,7 +736,7 @@ func sendUpRTCP(conn *rtpUpConnection) error { } reports = append(reports, rtcp.ReceptionReport{ - SSRC: t.track.SSRC(), + SSRC: uint32(t.track.SSRC()), FractionLost: uint8((lost * 256) / expected), TotalLost: totalLost, LastSequenceNumber: eseqno, @@ -767,7 +768,7 @@ func sendUpRTCP(conn *rtpUpConnection) error { if t.hasRtcpFb("goog-remb", "") { continue } - ssrcs = append(ssrcs, t.track.SSRC()) + ssrcs = append(ssrcs, uint32(t.track.SSRC())) } if len(ssrcs) > 0 { @@ -823,7 +824,7 @@ func sendSR(conn *rtpDownConnection) error { p, b := t.rate.Totals() packets = append(packets, &rtcp.SenderReport{ - SSRC: t.track.SSRC(), + SSRC: uint32(t.ssrc), NTPTime: nowNTP, RTPTime: nowRTP, PacketCount: p, @@ -843,7 +844,7 @@ func sendSR(conn *rtpDownConnection) error { &rtcp.SourceDescription{ Chunks: []rtcp.SourceDescriptionChunk{ { - Source: t.track.SSRC(), + Source: uint32(t.ssrc), Items: []rtcp.SourceDescriptionItem{item}, }, }, @@ -953,7 +954,7 @@ func rtcpDownListener(conn *rtpDownConnection, track *rtpDownTrack, s *webrtc.RT found := false var seqno uint8 for _, entry := range p.FIR { - if entry.SSRC == track.track.SSRC() { + if entry.SSRC == uint32(track.ssrc) { found = true seqno = entry.SequenceNumber break @@ -992,13 +993,13 @@ func rtcpDownListener(conn *rtpDownConnection, track *rtpDownTrack, s *webrtc.RT conn.maxREMBBitrate.Set(p.Bitrate, jiffies) case *rtcp.ReceiverReport: for _, r := range p.Reports { - if r.SSRC == track.track.SSRC() { + if r.SSRC == uint32(track.ssrc) { handleReport(track, r, jiffies) } } case *rtcp.SenderReport: for _, r := range p.Reports { - if r.SSRC == track.track.SSRC() { + if r.SSRC == uint32(track.ssrc) { handleReport(track, r, jiffies) } } @@ -1037,7 +1038,7 @@ func handleReport(track *rtpDownTrack, report rtcp.ReceptionReport, jiffies uint } } -func minPacketCache(track *webrtc.Track) int { +func minPacketCache(track *webrtc.TrackRemote) int { if track.Kind() == webrtc.RTPCodecTypeVideo { return 128 } diff --git a/rtpconn/rtpreader.go b/rtpconn/rtpreader.go index 65c850a..5b0771a 100644 --- a/rtpconn/rtpreader.go +++ b/rtpconn/rtpreader.go @@ -3,6 +3,7 @@ package rtpconn import ( "io" "log" + "strings" "github.com/pion/rtp" "github.com/pion/rtp/codecs" @@ -31,7 +32,7 @@ func readLoop(conn *rtpUpConnection, track *rtpUpTrack) { }() isvideo := track.track.Kind() == webrtc.RTPCodecTypeVideo - codec := track.track.Codec().Name + codec := track.track.Codec() sendNACK := track.hasRtcpFb("nack", "") buf := make([]byte, packetcache.BufSize) var packet rtp.Packet @@ -54,7 +55,7 @@ func readLoop(conn *rtpUpConnection, track *rtpUpTrack) { track.jitter.Accumulate(packet.Timestamp) kf := false - if isvideo && codec == webrtc.VP8 { + if isvideo && strings.ToLower(codec.MimeType) == "video/vp8" { kf = isVP8Keyframe(&packet) } diff --git a/rtpconn/rtpwriter.go b/rtpconn/rtpwriter.go index 86c753e..f6d71fa 100644 --- a/rtpconn/rtpwriter.go +++ b/rtpconn/rtpwriter.go @@ -4,10 +4,10 @@ import ( "errors" "log" "sort" + "strings" "time" "github.com/pion/rtp" - "github.com/pion/webrtc/v3" "sfu/conn" "sfu/packetcache" @@ -241,7 +241,7 @@ const ( func rtpWriterLoop(writer *rtpWriter, up *rtpUpConnection, track *rtpUpTrack) { defer close(writer.done) - codec := track.track.Codec().Name + codec := track.track.Codec() buf := make([]byte, packetcache.BufSize) var packet rtp.Packet @@ -277,7 +277,8 @@ func rtpWriterLoop(writer *rtpWriter, up *rtpUpConnection, track *rtpUpTrack) { found, _, lts := track.cache.Last() kts, _, kf := track.cache.Keyframe() - if codec == webrtc.VP8 && found && len(kf) > 0 { + if strings.ToLower(codec.MimeType) == "video/vp8" && + found && len(kf) > 0 { if ((lts-kts)&0x80000000) != 0 || lts-kts < 2*90000 { // we got a recent keyframe @@ -344,8 +345,8 @@ func rtpWriterLoop(writer *rtpWriter, up *rtpUpConnection, track *rtpUpTrack) { if kfNeeded > kfUnneeded { kf := false kfValid := false - switch codec { - case webrtc.VP8: + switch codec.MimeType { + case "video/vp8": kf = isVP8Keyframe(&packet) kfValid = true } diff --git a/rtpconn/webclient.go b/rtpconn/webclient.go index 39000ce..f5555a8 100644 --- a/rtpconn/webclient.go +++ b/rtpconn/webclient.go @@ -381,31 +381,32 @@ func delDownConnHelper(c *webClient, id string) *rtpDownConnection { } func addDownTrack(c *webClient, conn *rtpDownConnection, remoteTrack conn.UpTrack, remoteConn conn.Up) (*webrtc.RTPSender, error) { - var pt uint8 - var ssrc uint32 - var id, label string - switch rt := remoteTrack.(type) { - case *rtpUpTrack: - pt = rt.track.PayloadType() - ssrc = rt.track.SSRC() - id = rt.track.ID() - label = rt.track.Label() - default: - return nil, errors.New("not implemented yet") + rt, ok := remoteTrack.(*rtpUpTrack) + if !ok { + return nil, errors.New("unexpected up track type") } - local, err := conn.pc.NewTrack(pt, ssrc, id, label) + local, err := webrtc.NewTrackLocalStaticRTP( + remoteTrack.Codec(), + rt.track.ID(), rt.track.StreamID(), + ) if err != nil { return nil, err } - s, err := conn.pc.AddTrack(local) + sender, err := conn.pc.AddTrack(local) if err != nil { return nil, err } + parms := sender.GetParameters() + if len(parms.Encodings) != 1 { + return nil, errors.New("got multiple encodings") + } + track := &rtpDownTrack{ track: local, + ssrc: parms.Encodings[0].SSRC, remote: remoteTrack, maxBitrate: new(bitrate), stats: new(receiverStats), @@ -413,9 +414,9 @@ func addDownTrack(c *webClient, conn *rtpDownConnection, remoteTrack conn.UpTrac } conn.tracks = append(conn.tracks, track) - go rtcpDownListener(conn, track, s) + go rtcpDownListener(conn, track, sender) - return s, nil + return sender, nil } func negotiate(c *webClient, down *rtpDownConnection, renegotiate, restartIce bool) error { @@ -432,7 +433,7 @@ func negotiate(c *webClient, down *rtpDownConnection, renegotiate, restartIce bo labels := make(map[string]string) for _, t := range down.pc.GetTransceivers() { - var track *webrtc.Track + var track webrtc.TrackLocal if t.Sender() != nil { track = t.Sender().Track() }