【问题标题】:DOMException: Failed to set remote offer sdp: Called in wrong state: STATE_SENTOFFERDOMException:无法设置远程报价 sdp:在错误状态下调用:STATE_SENTOFFER
【发布时间】:2016-10-13 17:33:25
【问题描述】:

我正在尝试使用 webRTC 制作视频通话网络应用程序。我正在使用 angularjs 和 express.io

我收到此错误: DOMException:无法设置远程报价 sdp:在错误状态下调用:STATE_SENTOFFER

我的一些代码是:

// in controller (socket is already defined in controller)
var videolocal = document.getElementById('videolocal');
var videoremote = document.getElementById('videoremote');
var streamlocal = null;
var pc = null;
window.URL = window.URL || window.webkitURL;
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
window.RTCPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection;

var configuration = {'iceServers': [
        // {'url': 'stun:stun.services.mozilla.com'}, 
        {'url': 'stun:stun.l.google.com:19302'}
    ]};

// run start(true) to initiate a call
$scope.start = function() {
    console.log('start');

    // get the local stream, show it in the local video element and send it
    navigator.getUserMedia({ "audio": true, "video": true }, function (stream) {
        videolocal.src = URL.createObjectURL(stream);
        pc = new RTCPeerConnection(configuration);
        pc.addStream(stream);

        // once remote stream arrives, show it in the remote video element
        pc.onaddstream = function (evt) {
            console.log('onaddstream');
            videoremote.src = URL.createObjectURL(evt.stream);
        };

        // send any ice candidates to the other peer
        pc.onicecandidate = function (evt) {
            console.log('onicecandidate');
            if(evt.candidate){
                socket.emit('video_call',{user:2, type: 'candidate', candidate: evt.candidate});
            }                       
        };                          

        // create an offer 
        pc.createOffer(function (offer) {
            socket.emit('video_call', {user:2,  type: "offer", offer: offer}); 
            pc.setLocalDescription(offer);
        }, function (error) { 
            alert("Error when creating an offer"); 
        });
    }, function () {alert('error in start')});
}
$scope.start();

socket.on('video_call', function (data) {
    console.log(data);
    //when somebody sends us an offer 
    function handleOffer(offer) {
        // this line is giving error
        pc.setRemoteDescription(new RTCSessionDescription(offer), function(){alert('success')}, function(e){ console.log(e); alert(e)});

        //create an answer to an offer 
        pc.createAnswer(function (answer) { 
            pc.setLocalDescription(answer); 
            socket.emit('video_call', {user:2, type: "answer", answer: answer});                            
        }, function (error) {
            console.log(error); 
            alert("Error when creating an answer"); 
        }); 
    };

    //when we got an answer from a remote user
    function handleAnswer(answer) { 
       pc.setRemoteDescription(new RTCSessionDescription(answer)); 
    };

    //when we got an ice candidate from a remote user 
    function handleCandidate(candidate) { 
       pc.addIceCandidate(new RTCIceCandidate(candidate)); 
    };

    switch(data['type']) { 
        case "offer": 
            handleOffer(data["offer"]); 
            break; 
        case "answer": 
            handleAnswer(data['answer']); 
            break; 
        //when a remote peer sends an ice candidate to us 
        case "candidate": 
            handleCandidate(data['candidate']); 
            break; 
        default:
            break; 
   }
});

在服务器上:

// this function is called on video_call event
video_call: function (data) {
    var id = data.user; 

    // if user is active
    // users is dict of users (user_id as key)
    if(Object.keys(users).indexOf(id.toString()) > -1){
        // for each device of the user
        users[id].forEach(function(user_socket){
            console.log(data);
            user_socket.emit('video_call', data);               
        });
    }
}

请谁能告诉我这段代码有什么问题。本地流正在正确捕获。我正在使用铬浏览器。

服务器上的数据:

【问题讨论】:

  • JS 中产生此错误的确切行是什么?
  • 收到offer时,这一行"pc.setRemoteDescription(new RTCSessionDescription(offer), function(){alert('success')}, function(e){ console.log(e) ; 警报(e)});"正在发出警报(并且还在控制台中打印):DOMException:无法设置远程报价 sdp:在错误状态下调用:STATE_SENTOFFER。然后它打印: Uncaught (in promise) DOMException: Error processing ICE Candidate

标签: webrtc


【解决方案1】:

我认为问题在于,在您的 handleOffer() 函数中,您需要创建另一个 PeerConnection 并在该电脑上调用 setRemoteDescription()

var remote_pc = new RTCPeerConnection(configuration)
remote_pc.setRemoteDescription(new RTCSessionDescription(offer), ...) {
  remote_pc.createAnswer()
}

这就是我的代码中的内容。

编辑:official link 中,您可以转到第 11.7 章并检查 15 之后的步骤(当发送报价并且其他对等方收到报价时)。

【讨论】:

  • 现在我收到此错误:未捕获(承诺中)DOMException:处理 ICE 候选者时出错。请您分享最简单的工作示例前端代码。
  • 我无法共享所有代码,因为我的公司是所有者...您是否将pc.addIceCandidate() 更改为remote_pc?您需要区分这 2 个 peerConnections。
  • 如何链接remote_pc和videoremote(远程元素的视频标签)?
  • 事件onaddstream接收远程视频。你已经实现了。
  • 我没有在不同的电脑上检查过。检查后我将用完整的代码更新这个答案。感谢您的帮助。
猜你喜欢
  • 2021-05-09
  • 1970-01-01
  • 1970-01-01
  • 2018-03-09
  • 1970-01-01
  • 2022-08-21
  • 1970-01-01
  • 2022-10-01
  • 1970-01-01
相关资源
最近更新 更多