问题描述
我开始使用WebRTC进行开发,但是那件事从来没有给我ICE候选人.我设置了所有内容,交换了说明和内容,还缩小了一个超级丑陋的功能,以确保所有内容都能正确运行.两者的信号状态都是稳定的, onError 从未触发(如预期的那样),但是onIceCandidate也(未如预期的那样)以及我想发送随机的空MediaStream对象 pc1.addStream时都保持稳定(new webkitMediaStream());
,它始终会触发 onNegotiationNeeded .
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.
有人知道我的代码到底有什么问题吗?我花了数小时浏览Stack Overflow,HTML5 Rocks和W3C文档,但我不明白.这是我的整个代码:
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:
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);
顺便说一句,我正在使用Google Chrome浏览器进行开发.我将确保它也可以在Firefox中运行,但是现在问题应该是跨浏览器.我想在进入数据通道之前...(但我对使用Firefox或跨浏览器代码的有效解决方案一无所知)
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)
推荐答案
在Chrome 38及更低版本中, OfferToReceiveAudio
默认设置为 true
.从Chrome 39开始, OfferToReceiveAudio
默认为false,这是WebRTC工程师在 PSA:将行为更改为PeerConnection.createOffer约束OfferToReceiveAudio (在下面引用).
由于此更改, createOffer
返回的SDP不包含任何媒体,因此ICE收集过程永远不会开始.通过观察ICE事件从未触发,并且PeerConnection的 iceGatheringState
和 iceConnectionState
保持新"状态,您可以注意到此更改的后果.
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).
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".
要确保ICE收集开始并完成,您必须将媒体添加到报价中,例如通过在要约中的以下约束中设置 OfferToReceiveAudio:true
(可以作为 PeerConnection
构造函数,或作为 peerConnection.createOffer
方法):
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):
{
mandatory: {
OfferToReceiveAudio: true
}
}
(在SDP中获取媒体的其他方法包括设置 OfferToReceiveVideo:true
或调用 peerConnection.addStream
以及从 getUserMedia
获得的媒体流)
(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
)
webrtc-discuss: PSA:行为更改为PeerConnection.createOffer约束OfferToReceiveAudio :
webrtc-discuss: PSA: Behavior change to PeerConnection.createOffer constraint OfferToReceiveAudio:
更改之处:
当前,如果在PeerConnection.createOffer中未指定OfferToReceiveAudio约束,则即使没有音频轨道附加到PeerConnection,生成的商品SDP也将具有"m = audio"行.换句话说,OfferToReceiveAudio默认为true.
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.
更改后,OfferToReceiveAudio不再默认为true.要约SDP是否具有"m = audio"行,取决于是否在PeerConnection上附加了任何音轨.
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.
未更改的地方:
为OfferToReceiveAudio设置显式值的行为保持不变,即OfferToReceiveAudio:true将导致"m = audio"行,而不管是否存在音轨;不管是否存在音轨,OfferToReceiveAudio:false都不会导致"m = audio"行,除非已使用包含"m = audio"行的SDP调用了setLocalDescription,在这种情况下,新的提议SDP将标记音频内容而不是删除音频内容.
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.
这篇关于WebRTC永远不会在IceCandidate上触发的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!