Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DOMException: Failed to set remote offer sdp: Called in wrong state: STATE_SENTOFFER

Tags:

webrtc

I am trying to make a video calling web application using webRTC. I am using angularjs and express.io

I am getting this error: DOMException: Failed to set remote offer sdp: Called in wrong state: STATE_SENTOFFER

Some of my code is:

// 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; 
   }
});

On server:

// 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);               
        });
    }
}

Please can anyone tell what is wrong with this code. The local stream is capturing properly. I am using chromium browser.

Data on server: enter image description here

like image 456
Harish Kumar Avatar asked Jun 13 '16 10:06

Harish Kumar


1 Answers

I think the problem is that in your handleOffer() function you need to create another PeerConnection and call setRemoteDescription() on that pc.

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

This is what I have in my code.

EDIT: In the official link you can go to chapter 11.7 and check the steps after 15 (when the offer is sent and the other peer receives it).

like image 160
Samuel Méndez Avatar answered Oct 19 '22 16:10

Samuel Méndez