【问题标题】:WebRTC Firefox: Not enough arguments to RTCPeerConnection.setLocalDescriptionWebRTC Firefox:RTCPeerConnection.setLocalDescription 的参数不足
【发布时间】:2016-06-25 18:57:59
【问题描述】:

我正在使用 WebRTC 开发一个网络平台,以创建一个用于面试的点对点视频对话。使用 ASP.NET SignalR 建立通信。这是建立连接的javascript:

function initInterview() {
                //Gets user's media

                navigator.getUserMedia({ video: true, audio: true }, function (stream) {
                    // Display local stream to the user
                    var localMediaElem = document.querySelector('video#me');
                    localMediaElem.volume = 0.0;
                    localMediaElem.srcObject = stream;

                    // Assign stream
                    _myMediaStream = stream;

                    showUI(true);

                    console.log("Added local media stream");

                    // No startInterview call (waiting for interviewee to create offer)
                }, function (event) {
                    // Something failed
                    console.log(event);
                });
            };

            function _createConnection() {
                console.log('Creating RTCPeerConnection...');

                // Create a new PeerConnection
                var connection = new RTCPeerConnection(null); // null = no ICE servers

                // A new ICE candidate was found
                connection.onicecandidate = function (event) {
                    if (event.candidate) {
                        // Let's send it to our peer via SignalR
                        interview.server.send(interviewGuid, JSON.stringify({ "candidate": event.candidate }));
                    }
                };

                // New remote media stream was added
                connection.onaddstream = function (event) {
                    // Get other video element
                    var newVideoElement = document.querySelector('video#other');

                    // Attach the stream to the Video element via adapter.js
                    newVideoElement.srcObject = event.stream;
                };

                return connection;
            }

            // Callback that receives notifications from the SignalR server
            interview.client.newMessage = function (data) {
                console.log("Received message");
                console.log(data);
                var message = JSON.parse(data),
                    connection = _myConnection || _createConnection(null);

                // An SDP message contains connection and media information, and is either an 'offer' or an 'answer'
                if (message.sdp) {
                    console.log("Received session description");
                    connection.setRemoteDescription(new RTCSessionDescription(message.sdp), function () {
                        console.log("Description:");
                        console.log(connection.remoteDescription);
                        if (connection.remoteDescription.type == 'offer') {
                            console.log('received offer, sending answer...');

                            // Add our stream to the connection to be shared
                            connection.addStream(_myMediaStream);

                            // Create an SDP response
                            connection.createAnswer(function (desc) {
                                // Which becomes our local session description
                                connection.setLocalDescription(desc, function () {
                                    // And send it to the originator, where it will become their RemoteDescription
                                    interview.server.send(interviewGuid, JSON.stringify({ 'sdp': connection.localDescription }));
                                });
                            }, function (error) { console.log('Error creating session description: ' + error); });
                        } else if (connection.remoteDescription.type == 'answer') {
                            console.log('got an answer');
                        }
                    });
                } else if (message.candidate) {
                    console.log('adding ice candidate...');
                    connection.addIceCandidate(new RTCIceCandidate(message.candidate));
                }

                _myConnection = connection;
            };




            function startInterview() {
                console.log("Starting interview");

                _myConnection = _myConnection || _createConnection(null);

                // Add our stream to the peer connection
                _myConnection.addStream(_myMediaStream);

                // Create an offer to send our peer
                _myConnection.createOffer(function (desc) {
                    // Set the generated SDP to be our local session description
                    console.log(desc);
                    _myConnection.setLocalDescription(desc, function () {
                        // And send it to our peer, where it will become their RemoteDescription
                        interview.server.send(interviewGuid, JSON.stringify({ "sdp": desc }));
                    });
                }, function (error) { console.log('Error creating session description: ' + error); });
            };

受访者通过以下方式创建报价:

        function initInterview() {
                //Gets user's media

                navigator.getUserMedia({ video: true, audio: true }, function (stream) {
                    // Display local stream to the user
                    var localMediaElem = document.querySelector('video#me');
                    localMediaElem.volume = 0.0;
                    localMediaElem.srcObject = stream;

                    // Assign stream
                    _myMediaStream = stream;

                    showUI(true);

                    console.log("Added local media stream");

                    // Create offer for interviewer
                    startInterview();
                }, function (event) {
                    // Something failed
                    console.log(event);
                });
            };

当我们使用谷歌浏览器时它运行良好,但每当我们使用 Firefox 时,我们都会收到以下错误:

Started SignalR hub b39c24ad-bd2d-42bf-829a-176bda8e3905:224:21

Added local media stream b39c24ad-bd2d-42bf-829a-176bda8e3905:344:25

Starting interview b39c24ad-bd2d-42bf-829a-176bda8e3905:355:21
Creating RTCPeerConnection... b39c24ad-bd2d-42bf-829a-176bda8e3905:265:21
onaddstream is deprecated! Use peerConnection.ontrack instead.
RTCSessionDescription { type: "offer", sdp: "v=0 o=mozilla...THIS_IS_SDPARTA-47.…" } b39c24ad-bd2d-42bf-829a-176bda8e3905:365:25
Received message b39c24ad-bd2d-42bf-829a-176bda8e3905:292:21
"{"sdp":{"type":"offer","sdp":"v=[...]a0f1\r\n"}}" b39c24ad-bd2d-42bf-829a-176bda8e3905:293:21

Received session description b39c24ad-bd2d-42bf-829a-176bda8e3905:299:25

Received message b39c24ad-bd2d-42bf-829a-176bda8e3905:292:21

{"candidate":{"candidate":"candidate:2880323124 2 udp 2122260222 192.168.1.116 43234 typ host generation 0 ufrag bg8D7wuLUvtu/QjB network-id 1","sdpMid":"audio","sdpMLineIndex":0}} b39c24ad-bd2d-42bf-829a-176bda8e3905:293:21

adding ice candidate... b39c24ad-bd2d-42bf-829a-176bda8e3905:322:25

Received message b39c24ad-bd2d-42bf-829a-176bda8e3905:292:21

{"candidate":{"candidate":"candidate:2880323124 1 udp 2122260223 192.168.1.116 56886 typ host generation 0 ufrag bg8D7wuLUvtu/QjB network-id 1","sdpMid":"audio","sdpMLineIndex":0}} b39c24ad-bd2d-42bf-829a-176bda8e3905:293:21

[...]

{"candidate":{"candidate":"candidate:3844981444 2 tcp 1518280446 192.168.1.116 9 typ host tcptype active generation 0 ufrag bg8D7wuLUvtu/QjB network-id 1","sdpMid":"video","sdpMLineIndex":1}} b39c24ad-bd2d-42bf-829a-176bda8e3905:293:21

adding ice candidate... b39c24ad-bd2d-42bf-829a-176bda8e3905:322:25

TypeError: Not enough arguments to RTCPeerConnection.setLocalDescription.

【问题讨论】:

    标签: javascript asp.net-mvc firefox adapter webrtc


    【解决方案1】:

    setLocalDescription 可能失败,takes three arguments:描述、成功回调和失败回调。你错过了后者。 Chrome 是错误的。

    请注意,此旧 API 已被替换为 a modern one,而返回 promises

           if (message.sdp) {
               connection.setRemoteDescription(message.sdp).then(() => {
                   if (connection.remoteDescription.type == 'answer') {
                       return;
                   }
                   connection.addStream(_myMediaStream);
                   return connection.createAnswer()
                       .then(desc => connection.setLocalDescription(desc))
                       .then(() => interview.server.send(interviewGuid,
                           JSON.stringify({ 'sdp': connection.localDescription })));
               })
               .catch(error => console.log('Error: ' + error));
           } else if (message.candidate) {
               connection.addIceCandidate(message.candidate))
               .catch(error => console.error(error));
           }
    

    在旧版浏览器中使用 adapter.js(官方 WebRTC polyfill)访问它。

    【讨论】:

    • 使用此代码并更改了 connection.oniceccandidate 以使其工作:interview.server.send(interviewGuid, JSON.stringify({ "sdpMLineIndex": event.label, "candidate": event.candidate }));
    • @Zomtorg 嗯,sdpMLineIndex 通常是event.candidate 本身的属性,并且是一个数字。我想你可以对任何你喜欢的信号进行字符串化,但这是一个奇怪的名字,在浏览器 AFAIK 中没有特殊含义。
    猜你喜欢
    • 2017-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多