我正在尝试设置两个对等连接交换视频的视频聊天。这在创建数据通道后发生。所以这是事件的过程:
但是,如果我切换第2步和第3步(所以 answerer 首先开始流式传输),那么事情就会开始出错。双方只有在完成第1,3和2步之后才开始流式传输。
我很确定它与SDP提供和答案的顺序有关。
当我让回答者在有 onnegotiationneeded 事件时创建新要约时,行为会有所不同,但仍然不稳定。
我现在对如何添加优惠和答案毫无头绪。
以下是代码:
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
PeerConnection = window.mozRTCPeerConnection || window.webkitRTCPeerConnection || window.RTCPeerConnection;
IceCandidate = window.mozRTCIceCandidate || window.RTCIceCandidate || window.RTCIceCandidate;
SessionDescription = window.mozRTCSessionDescription || window.webkitRTCSessionDescription || window.RTCSessionDescription;
var videoOfferer = document.getElementById('videoOfferer');
var videoAnswerer = document.getElementById('videoAnswerer');
var buttonOfferer = document.getElementById('buttonOfferer');
var buttonAnswerer = document.getElementById('buttonAnswerer');
var servers = {
iceServers: [
{url: "stun:23.21.150.121"},
{url: "stun:stun.1.google.com:19302"}
]
};
var offerer = new PeerConnection(servers), answerer = new PeerConnection(servers);
var channelOfferer = null, channelAnswerer = null;
offerer.onicecandidate = function(e) {
if(e.candidate == null) return;
answerer.addIceCandidate(new IceCandidate(e.candidate), function(){}, error);
};
offerer.onaddstream = function(e) {
videoOfferer.src = URL.createObjectURL(e.stream);
videoOfferer.play();
};
answerer.onicecandidate = function(e) {
if(e.candidate == null) return;
offerer.addIceCandidate(new IceCandidate(e.candidate), function(){}, error);
};
answerer.onaddstream = function(e) {
videoAnswerer.src = URL.createObjectURL(e.stream);
videoAnswerer.play();
};
function offerCreated(sdp) {
console.log('offer');
offerer.setLocalDescription(new SessionDescription(sdp), function() {
answerer.setRemoteDescription(new SessionDescription(sdp), function() {
answerer.createAnswer(answerCreated, error);
}, error);
}, error);
}
function answerCreated(sdp) {
console.log('answer');
answerer.setLocalDescription(new SessionDescription(sdp), function() {
}, error);
offerer.setRemoteDescription(new SessionDescription(sdp), function() {
}, error);
}
function error() {}
buttonOfferer.addEventListener('click', function() {
navigator.getUserMedia({audio: true, video: true}, function(stream) {
offerer.addStream(stream);
}, function(){});
});
buttonAnswerer.addEventListener('click', function() {
navigator.getUserMedia({audio: true, video: true}, function(stream) {
answerer.addStream(stream);
}, function(){});
});
channelOfferer = offerer.createDataChannel('channel', {reliable: true});
offerer.createOffer(offerCreated, error);
answerer.ondatachannel = function(e) {
channelOfferer = e.channel;
channelOfferer.onmessage = function(e) {
console.log(e.data);
};
channelOfferer.onmessage = function(e) {
console.log(e.data);
};
// these are added later
offerer.onnegotiationneeded = function() {
offerer.createOffer(offerCreated, error);
};
answerer.onnegotiationneeded = function() {
offerer.createOffer(offerCreated, error);
};
};
答案 0 :(得分:3)
我认为问题出现在第3步中,当应答者添加视频时,您可以启动提议者。在一个真正的远程呼叫中,提议者怎么会知道这样做呢?
据我所知,当回答者需要重新协商时,角色会被有效地逆转,因为出于重新谈判的目的:重新谈判者充当提议者,而非重新谈判者充当提议者。回答者。
换句话说:对pc.onnegotiationneeded
的回复始终是:
createOffer()
,setLocalDescription(description)
pc.localDescription
发送到另一方无论哪一方。
我不是SDP的权威,所以我不确定这是正确的做法,但是the examples in the spec至少向我建议上面的步骤是正确的,我让它工作了这样。
我已经在this Firefox jsfiddle中对此进行了测试,但似乎有效。使用小提琴的说明:
Offer
按钮并复制优惠。addTrack
,视频应显示在另一端。addTrack
,您应该双向播放视频。这会产生眩光吗?我敢肯定,可能有更好的方法来解决这个问题,但这似乎对我有用。