javascript - WebRTC RTCPeerConnection not established - Stack Overflow

admin2025-04-21  0

My simple WebRTC javascript-code does not work as intended. In fact, the audio-call does not get established (Note that I have minimum-knowledge of WebRTC, I created this by looking at examples on the internet). The page should initiate an audio call between two participants. As signaling-server between participants I used a websocket-server. This server only relays messages beetween participants. During the call-initiation messages are really sent (one offer, several candidates, one answer and other candidates) via websocket.
Still, Firefox gives me "ICE failed, see about:webrtc for more details". Both participants are behind normal routers.
I will add the log of my websocket-server and an example of about:webrtc (shortened, of course) as soon as possible.

Why does this code not work? What did I overlook?

My code is (have in mind this only works in firefox):

ws = new WebSocket("ws://" + location.hostname + ":9000");
navigator.getUserMedia = function(a, b){ return navigator.mozGetUserMedia(a, b, error);};
offerOptions = {offerToRecieveAudio: 1, offerToRecieveVideo: 1};

var pc = new RTCPeerConnection({"iceServers": [
{url:'stun:stun.l.google:19302'},
{url:'stun:stunserver'},
]});
pc.onaddstream = function(obj) {
  if (obj.stream instanceof LocalMediaStream) return;
  var audio = document.createElement("audio");
  audio.controls = "true";
  audio.autoplay = "true";
  document.body.appendChild(audio);
  audio.srcObject = obj.stream;
}
pc.onicecandidate = function(evt){
        if (!evt.candidate) return;
        console.log(evt.candidate);
        ws.send(JSON.stringify(evt.candidate));
}

// Helper functions
function endCall() {
  var audios = document.getElementsByTagName("audio");
  for (var i = 0; i < audios.length; i++) {
    audios[i].pause();
  }

  pc.close();
}

function error(err) {
  endCall();
}

function startCall(){
        navigator.getUserMedia({audio: true}, function(stream) {
        pc.onaddstream({stream: stream});
       pc.addStream(stream);

        pc.createOffer(function(offer) {
                pc.setLocalDescription(new RTCSessionDescription(offer),function() {
                ws.send(JSON.stringify(offer));
                }, error, offerOptions);
        }, error);
        });
}

ws.onmessage = function(message){
        var m = JSON.parse(message.data);
        console.log(m);

        if (m.type){
                if (m.type == "offer"){
                        navigator.getUserMedia({audio: true}, function(stream) {
                        pc.onaddstream({stream: stream});
                        pc.addStream(stream);

                        pc.setRemoteDescription(new RTCSessionDescription(m), function() {
                                pc.createAnswer(function(answer) {
                                pc.setLocalDescription(new RTCSessionDescription(answer), function() {
                                        ws.send(JSON.stringify(answer));
                                }, error);
                                }, error, offerOptions);
                        }, error);
                        });
                 }
                if (m.type == "answer"){
                        pc.setRemoteDescription(new RTCSessionDescription(m), function() { }, error);
                }
        }
        if (m.candidate){
                pc.addIceCandidate(new RTCIceCandidate(m));
        }
};

To initiate a call, you should only call the properly named startCall()-function.

The websocket-munication between two gives (ip's removed):

Client connecting: tcp:ip1:62322
Client connecting: tcp:ip2:50075
Text message received: {"type":"offer","sdp":"v=0\r\no=mozilla...THIS_IS_SDPARTA-45.0.2 8467526262723029465 0 IN IP4 0.0.0.0\r\ns=-\r\nt=0 0\r\na=fingerprint:sha-256 8E:FC:F3:42:12:68:95:13:98:CC:B0:8D:41:F6:4E:39:19:60:70:5A:4B:4A:9D:93:4C:A0:53:CF:58:AB:3F:A1\r\na=ice-options:trickle\r\na=msid-semantic:WMS *\r\nm=audio 9 UDP/TLS/RTP/SAVPF 109 9 0 8\r\nc=IN IP4 0.0.0.0\r\na=sendrecv\r\na=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level\r\na=ice-pwd:0a7123357b97345c6f9a9474aabf0c27\r\na=ice-ufrag:5d02cec2\r\na=mid:sdparta_0\r\na=msid:{512da0cd-689a-4981-9d88-9e857ba62803} {f7e81293-42b4-44e1-9d5b-80afe2857cf8}\r\na=rtcp-mux\r\na=rtpmap:109 opus/48000/2\r\na=rtpmap:9 G722/8000/1\r\na=rtpmap:0 PCMU/8000\r\na=rtpmap:8 PCMA/8000\r\na=setup:actpass\r\na=ssrc:2285633480 cname:{90d0392b-c8f1-4be9-af57-8c34d08567cd}\r\n"}
Text message received: {"candidate":"candidate:0 1 UDP 2122187007 localip2 51858 typ host","sdpMid":"sdparta_0","sdpMLineIndex":0}
Text message received: {"candidate":"candidate:7 1 UDP 2122252543 ipv6-2 51859 typ host","sdpMid":"sdparta_0","sdpMLineIndex":0}
Text message received: {"candidate":"candidate:0 2 UDP 2122187006 ip2 51860 typ host","sdpMid":"sdparta_0","sdpMLineIndex":0}
Text message received: {"candidate":"candidate:7 2 UDP 2122252542 ipv6-2 52724 typ host","sdpMid":"sdparta_0","sdpMLineIndex":0}
Text message received: {"candidate":"candidate:2 1 UDP 1685987327 ip2 51858 typ srflx raddr localip2 rport 51858","sdpMid":"sdparta_0","sdpMLineIndex":0}
Text message received: {"candidate":"candidate:2 2 UDP 1685987326 ip2 51860 typ srflx raddr localip2 rport 51860","sdpMid":"sdparta_0","sdpMLineIndex":0}
Text message received: {"type":"answer","sdp":"v=0\r\no=mozilla...THIS_IS_SDPARTA-45.0.2 1868980908691513816 0 IN IP4 0.0.0.0\r\ns=-\r\nt=0 0\r\na=fingerprint:sha-256 04:2A:EB:AD:90:95:A3:A8:B8:3A:76:FE:3A:E7:DA:1F:D6:77:30:8A:87:BB:B9:3A:30:B4:9B:3D:E5:8F:58:04\r\na=ice-options:trickle\r\na=msid-semantic:WMS *\r\nm=audio 9 UDP/TLS/RTP/SAVPF 109\r\nc=IN IP4 0.0.0.0\r\na=sendrecv\r\na=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level\r\na=ice-pwd:b5665ac44d79e66c392408e08bdc32ee\r\na=ice-ufrag:1a8f59a4\r\na=mid:sdparta_0\r\na=msid:{358aa02b-b035-41a8-acf6-2b787a192c60} {28e8765a-4a56-42e3-8f45-897ca7c99c05}\r\na=rtcp-mux\r\na=rtpmap:109 opus/48000/2\r\na=setup:active\r\na=ssrc:3277858225 cname:{8cee2fed-1a9e-46b9-90d7-3cad80050f3b}\r\n"}
Text message received: {"candidate":"candidate:0 1 UDP 2122252543 localip1 59706 typ host","sdpMid":"sdparta_0","sdpMLineIndex":0}
Text message received: {"candidate":"candidate:1 1 UDP 1686052863 ip1 59706 typ srflx raddr localip1 rport 59706","sdpMid":"sdparta_0","sdpMLineIndex":0}

My simple WebRTC javascript-code does not work as intended. In fact, the audio-call does not get established (Note that I have minimum-knowledge of WebRTC, I created this by looking at examples on the internet). The page should initiate an audio call between two participants. As signaling-server between participants I used a websocket-server. This server only relays messages beetween participants. During the call-initiation messages are really sent (one offer, several candidates, one answer and other candidates) via websocket.
Still, Firefox gives me "ICE failed, see about:webrtc for more details". Both participants are behind normal routers.
I will add the log of my websocket-server and an example of about:webrtc (shortened, of course) as soon as possible.

Why does this code not work? What did I overlook?

My code is (have in mind this only works in firefox):

ws = new WebSocket("ws://" + location.hostname + ":9000");
navigator.getUserMedia = function(a, b){ return navigator.mozGetUserMedia(a, b, error);};
offerOptions = {offerToRecieveAudio: 1, offerToRecieveVideo: 1};

var pc = new RTCPeerConnection({"iceServers": [
{url:'stun:stun.l.google.:19302'},
{url:'stun:stunserver'},
]});
pc.onaddstream = function(obj) {
  if (obj.stream instanceof LocalMediaStream) return;
  var audio = document.createElement("audio");
  audio.controls = "true";
  audio.autoplay = "true";
  document.body.appendChild(audio);
  audio.srcObject = obj.stream;
}
pc.onicecandidate = function(evt){
        if (!evt.candidate) return;
        console.log(evt.candidate);
        ws.send(JSON.stringify(evt.candidate));
}

// Helper functions
function endCall() {
  var audios = document.getElementsByTagName("audio");
  for (var i = 0; i < audios.length; i++) {
    audios[i].pause();
  }

  pc.close();
}

function error(err) {
  endCall();
}

function startCall(){
        navigator.getUserMedia({audio: true}, function(stream) {
        pc.onaddstream({stream: stream});
       pc.addStream(stream);

        pc.createOffer(function(offer) {
                pc.setLocalDescription(new RTCSessionDescription(offer),function() {
                ws.send(JSON.stringify(offer));
                }, error, offerOptions);
        }, error);
        });
}

ws.onmessage = function(message){
        var m = JSON.parse(message.data);
        console.log(m);

        if (m.type){
                if (m.type == "offer"){
                        navigator.getUserMedia({audio: true}, function(stream) {
                        pc.onaddstream({stream: stream});
                        pc.addStream(stream);

                        pc.setRemoteDescription(new RTCSessionDescription(m), function() {
                                pc.createAnswer(function(answer) {
                                pc.setLocalDescription(new RTCSessionDescription(answer), function() {
                                        ws.send(JSON.stringify(answer));
                                }, error);
                                }, error, offerOptions);
                        }, error);
                        });
                 }
                if (m.type == "answer"){
                        pc.setRemoteDescription(new RTCSessionDescription(m), function() { }, error);
                }
        }
        if (m.candidate){
                pc.addIceCandidate(new RTCIceCandidate(m));
        }
};

To initiate a call, you should only call the properly named startCall()-function.

The websocket-munication between two gives (ip's removed):

Client connecting: tcp:ip1:62322
Client connecting: tcp:ip2:50075
Text message received: {"type":"offer","sdp":"v=0\r\no=mozilla...THIS_IS_SDPARTA-45.0.2 8467526262723029465 0 IN IP4 0.0.0.0\r\ns=-\r\nt=0 0\r\na=fingerprint:sha-256 8E:FC:F3:42:12:68:95:13:98:CC:B0:8D:41:F6:4E:39:19:60:70:5A:4B:4A:9D:93:4C:A0:53:CF:58:AB:3F:A1\r\na=ice-options:trickle\r\na=msid-semantic:WMS *\r\nm=audio 9 UDP/TLS/RTP/SAVPF 109 9 0 8\r\nc=IN IP4 0.0.0.0\r\na=sendrecv\r\na=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level\r\na=ice-pwd:0a7123357b97345c6f9a9474aabf0c27\r\na=ice-ufrag:5d02cec2\r\na=mid:sdparta_0\r\na=msid:{512da0cd-689a-4981-9d88-9e857ba62803} {f7e81293-42b4-44e1-9d5b-80afe2857cf8}\r\na=rtcp-mux\r\na=rtpmap:109 opus/48000/2\r\na=rtpmap:9 G722/8000/1\r\na=rtpmap:0 PCMU/8000\r\na=rtpmap:8 PCMA/8000\r\na=setup:actpass\r\na=ssrc:2285633480 cname:{90d0392b-c8f1-4be9-af57-8c34d08567cd}\r\n"}
Text message received: {"candidate":"candidate:0 1 UDP 2122187007 localip2 51858 typ host","sdpMid":"sdparta_0","sdpMLineIndex":0}
Text message received: {"candidate":"candidate:7 1 UDP 2122252543 ipv6-2 51859 typ host","sdpMid":"sdparta_0","sdpMLineIndex":0}
Text message received: {"candidate":"candidate:0 2 UDP 2122187006 ip2 51860 typ host","sdpMid":"sdparta_0","sdpMLineIndex":0}
Text message received: {"candidate":"candidate:7 2 UDP 2122252542 ipv6-2 52724 typ host","sdpMid":"sdparta_0","sdpMLineIndex":0}
Text message received: {"candidate":"candidate:2 1 UDP 1685987327 ip2 51858 typ srflx raddr localip2 rport 51858","sdpMid":"sdparta_0","sdpMLineIndex":0}
Text message received: {"candidate":"candidate:2 2 UDP 1685987326 ip2 51860 typ srflx raddr localip2 rport 51860","sdpMid":"sdparta_0","sdpMLineIndex":0}
Text message received: {"type":"answer","sdp":"v=0\r\no=mozilla...THIS_IS_SDPARTA-45.0.2 1868980908691513816 0 IN IP4 0.0.0.0\r\ns=-\r\nt=0 0\r\na=fingerprint:sha-256 04:2A:EB:AD:90:95:A3:A8:B8:3A:76:FE:3A:E7:DA:1F:D6:77:30:8A:87:BB:B9:3A:30:B4:9B:3D:E5:8F:58:04\r\na=ice-options:trickle\r\na=msid-semantic:WMS *\r\nm=audio 9 UDP/TLS/RTP/SAVPF 109\r\nc=IN IP4 0.0.0.0\r\na=sendrecv\r\na=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level\r\na=ice-pwd:b5665ac44d79e66c392408e08bdc32ee\r\na=ice-ufrag:1a8f59a4\r\na=mid:sdparta_0\r\na=msid:{358aa02b-b035-41a8-acf6-2b787a192c60} {28e8765a-4a56-42e3-8f45-897ca7c99c05}\r\na=rtcp-mux\r\na=rtpmap:109 opus/48000/2\r\na=setup:active\r\na=ssrc:3277858225 cname:{8cee2fed-1a9e-46b9-90d7-3cad80050f3b}\r\n"}
Text message received: {"candidate":"candidate:0 1 UDP 2122252543 localip1 59706 typ host","sdpMid":"sdparta_0","sdpMLineIndex":0}
Text message received: {"candidate":"candidate:1 1 UDP 1686052863 ip1 59706 typ srflx raddr localip1 rport 59706","sdpMid":"sdparta_0","sdpMLineIndex":0}
Share Improve this question edited Apr 20, 2016 at 18:54 Sirac asked Apr 20, 2016 at 17:54 SiracSirac 6934 silver badges19 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 5

Change this line:

    if (m.candidate){
            pc.addIceCandidate(new RTCIceCandidate(m));
    }

to:

    if (m.candidate){
            pc.addIceCandidate(new RTCIceCandidate(m.candidate))
            .catch(e => console.error(e));
    }

In general what you're doing wrong is not logging errors like err. Change:

function error(err) {
  endCall();
}

to:

function error(err) {
  console.error(err);
  endCall();
}

The browser is trying to help you, and will often tell you what is wrong. This way you wont have to ask on SO next time something doesn't work.

Update:

The InvalidStateError: Cannot add ICE candidate in state stable means the callee is receiving candidates before it has received an offer. This is a timing sensitive part of WebRTC. Once setLocalDescription has been called on the caller's end, ice candidates start to flow. e.g. The wire will look like this:

offer, candidate, candidate, candidate

So on the receiving end you should call setRemoteDescription right away, otherwise that peer connection isn't ready to receive candidates. Your code is waiting on getUserMedia, is the problem.

Change your code to call setRemoteDescription before getUserMedia, and it should work better.

You haven't configured any TURN server, so as you see there are no Relay candidates in your candidate list. So likely that two participant are in a scenario where peer-to-peer is not possible using WebRTC, which requires a relay connection. So configuring TURN server might resolve your problem. To verify that this is the case you can try setup a call when both participant are behind same subnet or network where peer-to-peer should be possible and if that works then your code is Ok and configuring a TURN server will resolve your problem.

转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1745242155a292075.html

最新回复(0)