0

我想用 nodejs 和 webrtc 进行语音通话。当我打电话给其他用户时,出现错误“ICE 失败,请参阅 about:webrtc 了解更多详细信息”。HTML 仅包含一个调用 offer() 的按钮。

我可以确认报价和 SessionDescriptions 成功地从一个客户转移到另一个客户。请帮我

 Client Side Javasrcipt: 
    navigator.getUserMedia({video:false, audio:true}, function(stream)                 {
document.getElementById("localvideo").mozSrcObject = stream;
document.getElementById("localvideo").play();
document.getElementById("localvideo").muted = true;

// var pc = new mozRTCPeerConnection();
var pc = new PeerConnection(iceServers, options);
pc.addStream(stream);

pc.onaddstream = function(obj) {
log("Got onaddstream of type " + obj.type);
document.getElementById("remotevideo").mozSrcObject = obj.stream;
document.getElementById("remotevideo").play();
document.getElementById("dialing").style.display = "none";
document.getElementById("hangup").style.display = "block";
};

pc.createOffer(function(offer) {
console.log("Created offer" + JSON.stringify(offer));
pc.setLocalDescription(offer, function() {
// Send offer to remote end.       
pc.iceCandidate = new RTCIceCandidate();      
console.log(pc.iceCandidate);
    peerc = pc;
    jQuery.post(
      "offer", {
        to: user,
        from: document.getElementById("user").innerHTML,
        offer: JSON.stringify(offer)
      },
      function() { console.log("Offer sent!"); }
    ).error(error);
  }, error);
}, error);

});

还有我的服务器端脚本-

        app.post("/offer", function(req, res) { 
          var channel = users[req.body.to];
           channel.write("event: offer\n");
          channel.write("data: " + JSON.stringify(req.body));
          channel.write("\n\n");
          res.send(200);
        });
4

3 回答 3

2

我不是这里的情况,要么您没有提供完整的应用程序代码,要么您用于正确 webrtc 连接的应用程序代码不完整,

对于初学者来说,尽管 webrtc 简化了视频聊天,但简单地发送 offer sdp 并不能解决问题(我假设您在另一端创建了 answer sdp 并发送它),您还必须交换 ICE 候选人. 由于同行的冰候选人有点像他们的电话卡告诉他们如何联系到他们。因此,如果不交换它们,它们就无法进行交流。

在此处输入图像描述

通常,浏览器会为您提供ice 候选onIceCandidate事件,您将其发送给您的同行,它会将其添加为peerConnection.addIceCandidate(candidate),最初当我开始时,这个文档确实帮助我理解了WebRTC 的基础知识,您可以尝试一下。

于 2015-07-16T03:18:27.537 回答
1

您需要添加接收端并处理 ICE 候选人。我看到了,createOffer但没有看到createAnswer,ICE 失败可能是因为没有向 ICE 候选人发出信号(一种称为 Trickle ICE 的做法,现在需要这样做)。

看起来你正在使用 Firefox,所以你应该能够运行这个本地循环演示(无信号),我仍然希望指出缺少的部分来关闭循环。我使用视频是因为音频在本地循环中非常糟糕,原因很明显(反馈):

var pc1 = new mozRTCPeerConnection(), pc2 = new mozRTCPeerConnection();

pc1.onicecandidate = e => !e.candidate ||
    pc2.addIceCandidate(e.candidate).catch(failed);
pc2.onicecandidate = e => !e.candidate ||
    pc1.addIceCandidate(e.candidate).catch(failed);
pc2.onaddstream = e => v2.mozSrcObject = e.stream;

function start() {
  navigator.mediaDevices.getUserMedia({ video: true })
  .then(stream => pc1.addStream(v1.mozSrcObject = stream))
  .then(() => pc1.createOffer())
  .then(offer => pc1.setLocalDescription(offer))
  .then(() => pc2.setRemoteDescription(pc1.localDescription))
  .then(() => pc2.createAnswer())
  .then(answer => pc2.setLocalDescription(answer))
  .then(() => pc1.setRemoteDescription(pc2.localDescription))
  .then(() => log("Connected!"))
  .catch(failed);
}

var log = msg => div.innerHTML += "<p>" + msg + "</p>";
var failed = e => log(e +", line "+ e.lineNumber);
<video id="v1" height="120" width="160" autoplay></video>
<video id="v2" height="120" width="160" autoplay></video><br>
<button onclick="start()">Start!</button><div id="div"></div>

于 2015-07-16T05:44:03.573 回答
0

您是否在另一端生成答案并将其发送回第一方进行处理?

于 2015-07-16T04:22:03.077 回答