WebRTC的无服务器实现

时间:2015-04-16 14:57:32

标签: javascript webrtc serverless

我不知道我在实现无服务器WebRTC时遇到了什么问题。

  1. 创建优惠
  2. 将优惠传递给远程
  3. 创建答案
  4. 我不知道我在实现无服务器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");
    }
    

2 个答案:

答案 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上可能对您有帮助的代码。