WebRTC never fires onIceCandidate

题意:WebRTC 从未触发 onIceCandidate。

问题背景:

I started developing with WebRTC, but that thing never gives me ICE candidates. I set up everything, I'm exchanging the descriptions and stuff, I also made a super-ugly function narrow down there to make sure everything runs correctly, one after another. Signaling state is stable for both, onError is never fired (as expected), but onIceCandidate also (not as expected), and when I want to send a random, empty MediaStream object pc1.addStream(new webkitMediaStream());, it always fires onNegotiationNeeded.

我开始使用 WebRTC 开发,但它从未给我提供 ICE 候选者。我设置了一切,正在交换描述等,我还写了一个超级简单的函数来确保一切按顺序正确运行。信令状态对双方都很稳定,onError 从未触发(如预期),但 onIceCandidate 也没有触发(这不是预期的),而当我想发送一个随机的空 MediaStream 对象 pc1.addStream(new webkitMediaStream()); 时,它总是触发 onNegotiationNeeded。

Does anyone have an idea what the heck is wrong with my code? I spent hours of browsing Stack Overflow, HTML5 Rocks, and W3C docs, but I don't understand that. Here is my entire code:

有没有人知道我的代码出了什么问题?我花了几个小时浏览 Stack Overflow、HTML5 Rocks 和 W3C 文档,但仍然不明白。以下是我的完整代码:

var config={
  'iceServers':[{
    'url':'stun:stun.l.google.com:19302'
  },{
    'url':'stun:stun1.l.google.com:19302'
  },{
    'url':'stun:stun2.l.google.com:19302'
  },{
    'url':'stun:stun3.l.google.com:19302'
  },{
    'url':'stun:stun4.l.google.com:19302'
  }]
};
var pc1=new webkitRTCPeerConnection(config);
var pc2=new webkitRTCPeerConnection(config);

var onError=function(error)
{
  console.error(error);
}

pc1.onicecandidate=function()
{
  console.log('PC1 onIceCandidate (finally) fired!');
}
pc2.onicecandidate=function()
{
  console.log('PC2 onIceCandidate (finally) fired!');
}

pc1.oniceconnectionstatechange=function()
{
  console.log('PC1 oniceconnectionstatechange fired!');
}
pc2.oniceconnectionstatechange=function()
{
  console.log('PC2 oniceconnectionstatechange fired!');
}
pc1.onnegotiationneeded=function()
{
  console.log('PC1 onnegotiationneeded fired!');
}
pc2.onnegotiationneeded=function()
{
  console.log('PC2 onnegotiationneeded fired!');
}

pc1.createOffer(function(offer){
  pc1.setLocalDescription(offer,function(){
    pc2.setRemoteDescription(new RTCSessionDescription(offer),function(){
      pc2.createAnswer(function(answer){
        pc2.setLocalDescription(answer,function(){
          pc1.setRemoteDescription(new RTCSessionDescription(answer),new Function()/*I don't need you, bro*/,onError);
        },onError);
      },onError);
    },onError);
  },onError);
},onError);

BTW I'm developing with Google Chrome. I will make sure it also runs in Firefox, but right now the problem should be cross-browser. I want to make it to data channels before... (but I have nothing against a working solution with Firefox or cross-browser code)

顺便说一下,我是在 Google Chrome 中开发的。我会确保它在 Firefox 中也能运行,但目前这个问题应该是跨浏览器的。我想在数据通道之前实现……(不过我对能在 Firefox 或跨浏览器代码中工作的解决方案没有意见)。

问题解决:

In Chrome 38 and earlier, OfferToReceiveAudio defaulted to true. Starting from Chrome 39, OfferToReceiveAudio defaults to false, as announced by a WebRTC engineer at PSA: Behavior change to PeerConnection.createOffer constraint OfferToReceiveAudio (quoted below).

在 Chrome 38 及之前版本中,OfferToReceiveAudio 默认为 true。从 Chrome 39 开始,OfferToReceiveAudio 默认为 false,正如一位 WebRTC 工程师在 PSA 中所宣布的:PeerConnection.createOffer 约束 OfferToReceiveAudio 的行为变化(如下引用)。


Because of this change, the SDP returned by createOffer does not contain any media, and therefore the ICE gathering process never starts. You can notice the consequences of this change by observing that the ICE events are never triggered, and the PeerConnection's iceGatheringState and iceConnectionState stay "new".

由于这个变化,createOffer 返回的 SDP 不包含任何媒体,因此 ICE 收集过程从未开始。你可以通过观察 ICE 事件从未触发,以及 PeerConnection 的 iceGatheringState 和 iceConnectionState 始终保持为 "new",来注意到这一变化的后果。

To make sure that the ICE gathering starts and complete, you have to add media to your offer, e.g. by setting OfferToReceiveAudio:true in the following constraints to your offer (either as a parameter of the PeerConnection constructor, or as a parameter to the peerConnection.createOffer method):

为了确保 ICE 收集开始并完成,你必须在你的提议中添加媒体,例如通过在以下约束中设置 OfferToReceiveAudio: true(作为 PeerConnection 构造函数的参数或作为 peerConnection.createOffer 方法的参数):

{
    mandatory: {
        OfferToReceiveAudio: true
    }
}

(other ways to get media in the SDP include setting OfferToReceiveVideo:true, or calling peerConnection.addStream with a media stream that you got from getUserMedia)

(获取 SDP 中媒体的其他方法包括设置 OfferToReceiveVideo: true,或者使用从 getUserMedia 获取的媒体流调用 peerConnection.addStream)


webrtc-discuss: PSA: Behavior change to PeerConnection.createOffer constraint OfferToReceiveAudio:

I'm going to submit a change (https://webrtc-codereview.appspot.com/16309004/) to change the behavior of RTCPeerConnection.createOffer. The change is expected to be included in Chrome M39.

What's changed:

Currently if the OfferToReceiveAudio constraint is not specified in PeerConnection.createOffer, the resulted offer SDP will have an "m=audio" line even if there is no audio track attached to the PeerConnection. In other words, OfferToReceiveAudio defaults to true.

After my change, OfferToReceiveAudio no longer defaults to true. Whether the offer SDP has an "m=audio" line depends on if any audio track has been attached to the PeerConnection.

What's not changed:

The behavior of setting an explicit value for OfferToReceiveAudio remains the same, i.e. OfferToReceiveAudio:true will result in an "m=audio" line regardless of the existence of audio tracks; OfferToReceiveAudio:false will result in no "m=audio" line regardless of the existence of audio tracks, unless setLocalDescription has been called with an SDP containing an "m=audio" line, in which case the new offer SDP will mark the audio content inactive instead of removing the audio content.

猜你喜欢

转载自blog.csdn.net/suiusoar/article/details/143425500