我不知道我在实现无服务器WebRTC时遇到了什么问题。
我不知道我在实现无服务器WebRTC时遇到了什么问题。
这是我到目前为止所做的:
var localStream, localPeerConnection, remotePeerConnection;
var servers = {"iceServers":[{"url":"stun:23.21.150.121"}]};
var sdpConstraints = {
optional: [],
mandatory: {
OfferToReceiveAudio: true,
OfferToReceiveVideo: true
}
};
var localVideo = document.getElementById("alice");
var remoteVideo = document.getElementById("bob");
var startButton = document.getElementById("startButton");
var callButton = document.getElementById("callButton");
var hangupButton = document.getElementById("hangupButton");
var joinButton = document.getElementById("joinButton");
var localOffer = document.getElementById("localOffer");
var remoteOffer = document.getElementById("remoteOffer");
var localAnswer = document.getElementById("localAnswer");
var remoteAnswer = document.getElementById("remoteAnswer");
var showLocalOffer = document.getElementById("showLocalOffer");
var getRemoteOffer = document.getElementById("getRemoteOffer");
var showLocalAnswer = document.getElementById("showLocalAnswer");
var getRemoteAnswer = document.getElementById("getRemoteAnswer");
var sentLocalOfferButton = document.getElementById("sentLocalOfferButton");
var pasteRemoteOfferButton = document.getElementById("pasteRemoteOfferButton");
var sentLocalAnswerButton = document.getElementById("sentLocalAnswerButton");
var pasteRemoteAnswerButton = document.getElementById("pasteRemoteAnswerButton");
startButton.disabled = false;
callButton.disabled = true;
hangupButton.disabled = true;
joinButton.disabled = true;
showLocalOffer.style.display = 'none';
getRemoteOffer.style.display = 'none';
showLocalAnswer.style.display = 'none';
getRemoteAnswer.style.display = 'none';
startButton.onclick = start;
callButton.onclick = call;
joinButton.onclick = join;
hangupButton.onclick = hangup;
sentLocalOfferButton.onclick = showRemote;
pasteRemoteOfferButton.onclick = answerCreate;
pasteRemoteAnswerButton.onclick = answerRemote;
sentLocalAnswerButton.onclick = hideRemoteAnswer;
function trace(text) {
console.log((performance.now() / 1000).toFixed(3) + ": " + text);
}
function start() {
trace("Requesting local stream");
startButton.disabled = true;
getUserMedia({audio:true, video:true}, gotStream,
function(error) {
trace("getUserMedia error: ", error);
});
}
function gotStream(stream){
trace("Received local stream");
localVideo.src = URL.createObjectURL(stream);
localStream = stream;
callButton.disabled = false;
joinButton.disabled = false;
}
// ALICE
function call() {
showLocalOffer.style.display = 'block';
callButton.disabled = true;
joinButton.disabled = true;
hangupButton.disabled = false;
trace("Starting call");
if (localStream.getVideoTracks().length > 0) {
trace('Using video device: ' + localStream.getVideoTracks()[0].label);
}
if (localStream.getAudioTracks().length > 0) {
trace('Using audio device: ' + localStream.getAudioTracks()[0].label);
}
localPeerConnection = new RTCPeerConnection(servers);
trace("Created local peer connection object localPeerConnection");
localPeerConnection.addStream(localStream);
trace("Added localStream to localPeerConnection");
localPeerConnection.createOffer(gotLocalDescription,handleError,sdpConstraints);
}
function gotLocalDescription(description){
localPeerConnection.setLocalDescription(description);
trace("Offer from localPeerConnection SDP: \n" + description.sdp);
trace("Offer from localPeerConnection TYPE: \n" + description.type);
localOffer.value = JSON.stringify(description);
}
function showRemote() {
showLocalOffer.style.display = 'none';
getRemoteAnswer.style.display = 'block';
}
function answerRemote() {
getRemoteAnswer.style.display = 'none';
var remoteSesssionDescription = new RTCSessionDescription(JSON.parse(remoteAnswer.value));
localPeerConnection.setRemoteDescription(remoteSesssionDescription);
localPeerConnection.onaddstream = gotRemoteStream;
localPeerConnection.onicecandidate = gotRemoteIceCandidate;
}
function gotRemoteIceCandidate(evt) {
if (event.candidate) {
localPeerConnection.addIceCandidate(new RTCIceCandidate(evt.candidate));
trace("Remote ICE candidate: \n " + evt.candidate.candidate);
}
}
// BOB
function join() {
trace("Joining call");
getRemoteOffer.style.display = 'block';
callButton.disabled = true;
hangupButton.disabled = false;
joinButton.disabled = true;
remotePeerConnection = new RTCPeerConnection(servers);
trace("Created remote peer connection object remotePeerConnection");
}
function answerCreate() {
getRemoteOffer.style.display = 'none';
showLocalAnswer.style.display = 'block';
var sessionDescription = new RTCSessionDescription(JSON.parse(remoteOffer.value));
remotePeerConnection.setRemoteDescription(sessionDescription);
remotePeerConnection.createAnswer(gotRemoteDescription,handleError,sdpConstraints);
}
function gotRemoteDescription(answerSdp) {
remotePeerConnection.setLocalDescription(answerSdp);
trace("Answer from remotePeerConnection SDP: \n" + answerSdp.sdp);
trace("Answer from remotePeerConnection TYPE: \n" + answerSdp.type);
localAnswer.value = JSON.stringify(answerSdp);
remotePeerConnection.onaddstream = gotRemoteStream;
remotePeerConnection.onicecandidate = gotLocalIceCandidate;
}
function hideRemoteAnswer() {
showLocalAnswer.style.display = 'none';
}
function gotRemoteStream(evt) {
console.log('evt: ', evt);
remoteVideo.src = URL.createObjectURL(evt.stream);
trace("Received remote stream");
}
function gotLocalIceCandidate(evt){
if (event.candidate) {
remotePeerConnection.addIceCandidate(new RTCIceCandidate(evt.candidate));
trace("Local ICE candidate: \n" + evt.candidate.candidate);
}
}
// GENERAL USE
function hangup() {
trace("Ending call");
localPeerConnection = null;
remotePeerConnection = null;
hangupButton.disabled = true;
callButton.disabled = false;
joinButton.disabled = false;
showLocalOffer.style.display = 'none';
getRemoteOffer.style.display = 'none';
showLocalAnswer.style.display = 'none';
getRemoteAnswer.style.display = 'none';
}
function handleError(){
trace("Cannot Create Offer");
}
答案 0 :(得分:1)
我写过其中一个,你可以在this other answer的Firefox中试试。是的,通常使用服务器,只要它们可用,您就会通过信号通道发送ICE候选者。
但这里不切实际。我想您希望 一条 消息发送给您的朋友。要做到这一点,请等到浏览器有时间发现所有ICE候选人。然后,它们将包含在您的报价/答案中(注意:根据我的经验,这在Windows上可能需要15秒)。
执行此操作的一种方法是收听onnegotationneeded
,直到它返回一个空候选者,表示结冰:
pc.onicecandidate = function(e) {
if (e.candidate) return;
var offerSdp = pc.localDescription.sdp;
// send offerSdp string to friend
};
希望有所帮助。
答案 1 :(得分:0)
您应该使用onnegotationneeded
事件来检查是否需要协商。如果该事件被触发,您应该创建一个要约并进行交换。您可能需要查看github上可能对您有帮助的代码。