gpt4 book ai didi

javascript - WebRTC:Firefox 无法作为调用者接收视频

转载 作者:行者123 更新时间:2023-11-29 15:37:46 25 4
gpt4 key购买 nike

我是 WebRTC 的新手,正在尝试创建一个简单的测试页面,以允许进行一对一的视频 session 。

到目前为止,我的以下内容适用于以下内容:

  • Chrome -> Chrome
  • Firefox -> Chrome

它在以下情况下工作:

  • 火狐 -> 火狐
  • Chrome -> 火狐

基本上,Firefox在被调用时是无法接收远程视频流的。 onaddstream 处理程序从未被调用,但我不知道为什么。

我发现 Firefox 和 Chrome 之间的唯一区别是 Firefox 不会对 ICE 候选人进行细化;它们包含在最初的提议/答案创建中,导致 onicecandidate 处理程序永远不会被非空候选人调用。另一方面,Chrome 确实会细化候选者,这些候选者会作为单独的消息发送到信令服务器。我不确定这是否是一个/潜在的问题。

我正在使用 Firefox Nightly 34 和 Chrome 36 进行测试。信令服务器托管在我的 LAN 中,并且两个浏览器都在同一台计算机上运行。

以下代码基于 http://www.html5rocks.com/en/tutorials/webrtc/basics/ .

var localVideo;
var remoteVideo;
var peerConnection;
var peerConnectionConfig = {'iceServers': [{'url': 'stun:stun.services.mozilla.com'}, {'url': 'stun:stun.l.google.com:19302'}]};
var isCaller;

navigator.getUserMedia = navigator.getUserMedia || navigator.mozGetUserMedia || navigator.webkitGetUserMedia;
window.RTCPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
window.RTCIceCandidate = window.RTCIceCandidate || window.mozRTCIceCandidate || window.webkitRTCIceCandidate;
window.RTCSessionDescription = window.RTCSessionDescription || window.mozRTCSessionDescription || window.webkitRTCSessionDescription;

function pageReady() {
localVideo = document.getElementById('localVideo');
remoteVideo = document.getElementById('remoteVideo');

serverConnection = new WebSocket('ws://myserver:3434');
serverConnection.onmessage = gotMessageFromServer;
}

function start(_isCaller) {
isCaller = _isCaller

peerConnection = new RTCPeerConnection(peerConnectionConfig);
peerConnection.onicecandidate = gotIceCandidate;
peerConnection.onaddstream = gotRemoteStream;

var constraints = {
video: true,
audio: true,
};

if(navigator.getUserMedia) {
navigator.getUserMedia(constraints, getUserMediaSuccess, getUserMediaError);
} else {
alert('Your browser does not support getUserMedia API');
}
}

function getUserMediaSuccess(stream) {
localStream = stream;
localVideo.src = window.URL.createObjectURL(stream);

peerConnection.addStream(stream);

if(isCaller) {
peerConnection.createOffer(gotDescription, createOfferError);
} else {
peerConnection.createAnswer(gotDescription, createAnswerError);
}
}

function gotMessageFromServer(message) {
if(!peerConnection) start(false);

var signal = JSON.parse(message.data);
if(signal.sdp) {
peerConnection.setRemoteDescription(new RTCSessionDescription(signal.sdp));
} else if(signal.ice) {
peerConnection.addIceCandidate(new RTCIceCandidate(signal.ice));
}
}

function gotIceCandidate(event) {
if(event.candidate != null) {
serverConnection.send(JSON.stringify({'ice': event.candidate}));
}
}

function gotDescription(description) {
peerConnection.setLocalDescription(description);
serverConnection.send(JSON.stringify({'sdp': description}));
}

function gotMessageFromServer(message) {
if(!peerConnection) start(false);

var signal = JSON.parse(message.data);
if(signal.sdp) {
peerConnection.setRemoteDescription(new RTCSessionDescription(signal.sdp));
} else if(signal.ice) {
peerConnection.addIceCandidate(new RTCIceCandidate(signal.ice));
}
}

function gotRemoteStream(event) {
console.log("got remote stream");
remoteVideo.src = window.URL.createObjectURL(event.stream);
}

// Error functions....

function getUserMediaError(error) {
console.log(error);
}

function createOfferError(error) {
console.log(error);
}

function createAnswerError(error) {
console.log(error);
}

如果有用的话,这是我的信令服务器。这是一个非常基本的 Node.js 脚本,它使用 ws WebSocket 库将接收到的消息简单地广播到所有连接的客户端,在本例中只是一个其他客户端。

var WebSocketServer = require('ws').Server;

var wss = new WebSocketServer({port: 3434});

wss.broadcast = function(data) {
for(var i in this.clients) {
this.clients[i].send(data);
}
};

wss.on('connection', function(ws) {
ws.on('message', function(message) {
console.log('received: %s', message);
wss.broadcast(message);
});
});

非常感谢任何帮助!

最佳答案

原来我在调用 setRemoteDescription()createAnswer() 之间存在竞争条件。 Firefox 会在每次重新加载页面时请求使用网络摄像头的权限,而 Chrome 只会在第一个页面加载时请求。这意味着当我在 Firefox 中调用 createAnswer() 时,视频流还不存在,因为用户尚未允许访问网络摄像头。解决方案是将对 getUserMedia() 的调用移动到页面准备就绪时。这样,当来电发生时,用户已经允许访问网络摄像头,并且可以立即共享视频流。它并不完美,但它允许我的小测试页面正常工作,这就是我现在要做的。

这是更新后的代码,如果它对以后的任何人有帮助的话:

var localVideo;
var remoteVideo;
var peerConnection;
var peerConnectionConfig = {'iceServers': [{'url': 'stun:stun.services.mozilla.com'}, {'url': 'stun:stun.l.google.com:19302'}]};

navigator.getUserMedia = navigator.getUserMedia || navigator.mozGetUserMedia || navigator.webkitGetUserMedia;
window.RTCPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
window.RTCIceCandidate = window.RTCIceCandidate || window.mozRTCIceCandidate || window.webkitRTCIceCandidate;
window.RTCSessionDescription = window.RTCSessionDescription || window.mozRTCSessionDescription || window.webkitRTCSessionDescription;

function pageReady() {
localVideo = document.getElementById('localVideo');
remoteVideo = document.getElementById('remoteVideo');

serverConnection = new WebSocket('ws://sagan:3434');
serverConnection.onmessage = gotMessageFromServer;

var constraints = {
video: true,
audio: true,
};

if(navigator.getUserMedia) {
navigator.getUserMedia(constraints, getUserMediaSuccess, getUserMediaError);
} else {
alert('Your browser does not support getUserMedia API');
}
}

function getUserMediaSuccess(stream) {
localStream = stream;
localVideo.src = window.URL.createObjectURL(stream);
}

function start(isCaller) {
peerConnection = new RTCPeerConnection(peerConnectionConfig);
peerConnection.onicecandidate = gotIceCandidate;
peerConnection.onaddstream = gotRemoteStream;
peerConnection.addStream(localStream);

if(isCaller) {
peerConnection.createOffer(gotDescription, createOfferError);
}
}

function gotMessageFromServer(message) {
if(!peerConnection) start(false);

var signal = JSON.parse(message.data);
if(signal.sdp) {
peerConnection.setRemoteDescription(new RTCSessionDescription(signal.sdp), function() {
peerConnection.createAnswer(gotDescription, createAnswerError);
});
} else if(signal.ice) {
peerConnection.addIceCandidate(new RTCIceCandidate(signal.ice));
}
}

function gotIceCandidate(event) {
if(event.candidate != null) {
serverConnection.send(JSON.stringify({'ice': event.candidate}));
}
}

function gotDescription(description) {
console.log('got description');
peerConnection.setLocalDescription(description, function () {
serverConnection.send(JSON.stringify({'sdp': description}));
}, function() {console.log('set description error')});
}

function gotRemoteStream(event) {
console.log("got remote stream");
remoteVideo.src = window.URL.createObjectURL(event.stream);
}

// Error functions....

function getUserMediaError(error) {
console.log(error);
}

function createOfferError(error) {
console.log(error);
}

function createAnswerError(error) {
console.log(error);
}

关于javascript - WebRTC:Firefox 无法作为调用者接收视频,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25329135/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com