我在相关问题上阅读了其他几个问题,但没有人回答我的问题。我有一个奇怪的问题,我可以使用WebRTC从chrome到firefox进行音频聊天,但不能使用firefox到chrome。
基本上,当用户希望进行音频聊天时,他/她会点击按钮#audioChatBtn
,该按钮使用getUserMedia()
来设置流。问题是,点击Firefox中的#audioChatBtn
并未触发Chrome上的onaddstream
回调,但点击Chrome上的按钮会在Firefox上触发onaddstream
。因此,我可以从Chrome到Firefox进行音频聊天,但不是相反。我一直试图弄清楚这几个小时,但我希望也许有人在这里有答案。
相关来源:
var configuration = {
'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 pc = RTCPeerConnection(configuration);
var myStream = null;
var currentAudioIndex = 0; // Number of created channels
var myAudioEnabled = false;
// send any ice candidates to the other peer
pc.onicecandidate = function (evt) {
if (evt.candidate)
$(document).trigger("persistState", { mode: 'rtc', 'candidate': evt.candidate });
};
// let the 'negotiationneeded' event trigger offer generation
pc.onnegotiationneeded = function () {
pc.createOffer(localDescCreated, logError);
}
// once remote stream arrives, play it in the audio element
pc.onaddstream = function (evt) {
console.log('creating and binding audio');
var idx = (currentAudioIndex++);
var audioElement = $('#audio' + idx);
if (audioElement.length == 0) {
var audio = $('<audio id="audio' + idx + '" autoplay>');
$('body').append(audio);
audioElement = $('#audio' + idx);
}
var audioObject = audioElement[0];
attachMediaStream(audioObject, evt.stream);
};
function localDescCreated(desc) {
pc.setLocalDescription(desc, function () {
$(document).trigger("persistState", { mode: 'rtc', 'sdp': pc.localDescription });
}, logError);
}
function logError(e) {
bootbox.alert("Audio chat could not be started.");
}
function hasGetUserMedia() {
return !!(navigator.getUserMedia || navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia || navigator.msGetUserMedia);
}
server.onPersist = function(msg) {
if (msg.mode == "rtc") {
if (msg.sdp)
pc.setRemoteDescription(new RTCSessionDescription(msg.sdp), function () {
// if we received an offer, we need to answer
if (pc.remoteDescription.type == 'offer')
pc.createAnswer(localDescCreated, logError);
}, logError);
else
pc.addIceCandidate(new RTCIceCandidate(msg.candidate));
}
}
// On click, start audio chat from this user.
$('#audioChatBtn').click(function() {
if (!hasGetUserMedia()) {
bootbox.alert('Audio conferencing is not supported by your browser. (Currently only supported by Chrome, Firefox, and Opera web browsers.)');
return;
}
if (myAudioEnabled) {
myStream.stop();
displayAlert('Streaming closed', 'Audio chat is off');
$('#audioChatBtn').removeClass('btn-success').addClass('btn-primary');
} else {
getUserMedia({ video: false, audio: true }, function (localMediaStream) {
myStream = localMediaStream;
pc.addStream(localMediaStream);
displayAlert('Streaming...', 'Audio chat is enabled');
$('#audioChatBtn').removeClass('btn-primary').addClass('btn-success');
}, logError);
}
myAudioEnabled = !myAudioEnabled;
});
'optional': [{ 'DtlsSrtpKeyAgreement': 'true' }]
进行了尝试
getUserMedia()
答案 0 :(得分:5)
Firefox目前不支持onnegotiationneeded,因为我们目前不支持重新协商现有连接。所有addStream / addTrack和一个createDataChannel(如果你想使用它们)都需要在 createOffer()或createAnswer之前完成。连接后可以 createDataChannel(),如果你在createOffer之前创建的话。
在他们重新连接之后添加流不会工作。
(恼人的)替代方案是创建一组新的PeerConnections来替换旧的PeerConnections(使用旧对中的DataChannel作为信号通道以降低延迟)
在我们的优先级列表中解决这个问题很重要,但需要更多版本。
答案 1 :(得分:1)
经过大量的调试后,我意识到这个bug与我的代码无关,但与Firefox的WebRTC实现有关。 Firefox没有触发onnegotiationneeded
回调,因此我必须使用超时(并且希望)在函数触发之前将流信息中继到远程客户端)。显然,这是一个firefox错误,我会报告它,希望他们在下一个版本中修复bug。
getUserMedia({ video: false, audio: true }, function (localMediaStream) {
myStream = localMediaStream;
pc.addStream(localMediaStream);
displayAlert('Streaming...', 'Audio chat is enabled');
$('#audioChatBtn').removeClass('btn-primary').addClass('btn-success');
// Need this for Firefox
if (webrtcDetectedBrowser == 'firefox')
setTimeout(pc.onnegotiationneeded, 5000);
}, logError);