我正在尝试设置视频聊天,其中两个对等连接交换视频。创建数据通道后会发生这种情况。那么事件的流程是这样的:
-
offerer创建数据通道,offerer创造并提供,answerer创建一个答案。到目前为止,一切都很好。我们有一个数据通道。
-
offerer获取视频流获取用户媒体并将其添加到对等连接中,然后谈判的事件offerer fires, offerer创建新报价,同时answerer给出答案。还是一切都好。这offerer正在流式传输。
-
answerer获取视频流获取用户媒体并将其添加到对等连接中,offerer创建新报价,同时answerer给出答案。还在。这answerer也在流媒体。
但是,如果我交换步骤 2 和 3 (所以answerer首先开始流式传输)然后事情开始出错。只有在步骤 1、3 和 2 全部完成后,双方才可以开始直播。
我很确定这与 SDP 提供和答案的顺序有关。
当我让应答者创建一个新的报价时需要谈判如果行为不同但仍然不稳定。
我现在对如何添加优惠和答案一无所知。
这是代码:
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);
};
};