2016-11-19 58 views
0

我遇到了一个奇怪的问题,WebRTC的提供生成过程的抽象。看起来好像即将到来的冰候选人从未到达空候选人。在使用几乎相同的代码之前,我已经成功地生成了优惠,但无论出于何种原因,我的抽象版本只能达到12个候选人,而我原来的20个常规版本相比。这很奇怪,看起来代码几乎相同,但抽象的代码即使在同一浏览器上也不起作用。如何抽象WebRTC提供?

原工作代码:

var localConn = new webkitRTCPeerConnection({'iceServers':[{...}]}); 
    var remoteConn = new webkitRTCPeerConnection({'iceServers':[{...}]}); 

    function initMedia(localView, callback){ 
     navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia; 
     var constraints = {audio:true,video:true}; 
     navigator.getUserMedia(constraints, successStream, errorStream); 
     //onSuccess and Error functions 
     function successStream(stream){ 
      window.stream = stream; 
      if(window.URL){ 
       $('#'+localView).attr('src',window.URL.createObjectURL(stream)); 
      } else { 
       $('#'+localView).attr('src',stream); 
      } 
      localConn.addStream(stream); 
      remoteConn.addStream(stream); 
      console.log('local Stream: '+ stream.id); 
      callback();  //-> goes on to create new offer 
     } 
     function errorStream(error){ 
      console.log('navigator.getUserMedia error: ', error); 
     } 
    } 

    //function that generates offer and sends it out to a callback 
    function newOffer(callback){ 
     console.log('creating new offer'); 

     localConn.createOffer(function (sessionDescription){ 
      localConn.setLocalDescription(sessionDescription); 
     }, function(error){ 
      console.log('Error setting local description: '+error); 
     }); 
     createOffer(); 
     //gather ICE with a callback to handle/send generated offer 
     function createOffer(){ 
      localConn.onicecandidate = function(iceEvent){ 
       console.log('gathering local ice');  //ice events fired (20 total) 
       //upon gathering all local ice 
       if(iceEvent.candidate === null){ 
        console.log('local ice gathered'); //success 
        var offer = {'type': localConn.localDescription.type, 
           'sdp': localConn.localDescription.sdp}; 
        offer = JSON.stringify(offer); 
        console.log('offer created'); 
        callback(offer); 
       } 
      } 
     } 
    } 

新版本的抽象函数(没有得到空冰候选人)

//general rtc vars 
var localConn = new webkitRTCPeerConnection({'iceServers':[{'url':'stun:stun.1.google.com:19302'}]}); 
var remoteConn = new webkitRTCPeerConnection({'iceServers':[{'url':'stun:stun.1.google.com:19302'}]}); 
//var mediaStream; 
var channel; 

//creates a stream from webcam 
//@params function streamHandle(stream) 
function initStream(streamHandle){ 
    navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia; 
    var constraints = {audio:true,video:true}; 
    navigator.getUserMedia(constraints, successStream, errorStream); 
    //onSuccess and Error functions 
    function successStream(stream){ 
     window.stream = stream; 
     console.log('TreRTC: Local Stream-'+ stream.id); 
     //mediaStream = stream; 
     localConn.addStream(stream); //not sure if these need to be added before 
     remoteConn.addStream(stream); //or if they can be added in the creatOffer(stream) function 
     streamHandle(stream); //gets inserted into createOffer function 
    } 
    function errorStream(error){ 
     console.log('navigator.getUserMedia error: ', error); 
    } 
} 

//creates an offer to be sent 
//@params Stream stream (from getusermedia) 
//@return string offer 
function createOffer(stream){ 
    console.log('TreRTC: Creating Offer'); 
    //localConn.addStream(stream); //tried both ways from top and from internal 
    //remoteConn.addStream(stream); 

    localConn.createOffer(function (sessionDescription){ 
     localConn.setLocalDescription(sessionDescription); 
    }, function(error){ 
     console.log('Error setting local description: '+error); 
    }); 

    localConn.onicecandidate = function(iceEvt){ 
     console.log('TreRTC: ICE in');   //ice events firing (12 total) 
     if(iceEvt.candidate === null){ 
      console.log('TreRTC: ICE gathered'); //never reaches to this point... 
      var offer = {'type': localConn.localDescription.type, 
         'sdp': localConn.localDescription.sdp}; 
      offer = JSON.stringify(offer); 
      console.log('TreRTC: Offer initialized'); 
      return offer; //returns offer as a string 
     } //could also specify a callback 
    } 
} 
+1

请问你有什么依据例如该代码?它使用的是非常旧的构造,如传统的回调API [破坏的createObjectURL模式](http://stackoverflow.com/questions/40203036/how-stop-exit-video-in-webrtc-navigator-user-media-javascript/40210033#40210033),并且只能在Chrome浏览器启动时使用,因为webkit前缀(我试图追踪旧的示例以更新它们)。 – jib

+1

stun:stun.1.google.com:19305不是一个stun服务器。你可能想用stun.l.google.com:19305进行测试 –

回答

2
streamHandle(stream); //gets inserted into createOffer function 

你可能有你的createOffer功能,您initStream之间的竞争函数完成,因为当你计算他们设置的所有动作时,这两者实际上是异步的(很难确定,因为你没有显示该代码)。

如果你想抽象WebRTC,你应该考虑下车旧的传统API,而不是使用RTCPeerConnection的modern promise-methods。当谈到像这样处理比赛时,诺言是优秀的回调抽象。

还可以考虑使用onnegotiationneeded回调触发协商,以解决此问题(但要注意bug in Chrome)。

这里有一个本地连接的例子(使用https fiddle在Chrome):

var pc1 = new RTCPeerConnection(), pc2 = new RTCPeerConnection(); 
 

 
navigator.mediaDevices.getUserMedia({video: true, audio: true}) 
 
    .then(stream => pc1.addStream(video1.srcObject = stream)) 
 
    .catch(e => console.log(e)); 
 

 
pc1.onicecandidate = e => pc2.addIceCandidate(e.candidate); 
 
pc2.onicecandidate = e => pc1.addIceCandidate(e.candidate); 
 

 
pc2.ontrack = e => video2.srcObject = e.streams[0]; 
 
pc1.oniceconnectionstatechange = e => console.log(pc1.iceConnectionState); 
 
pc1.onnegotiationneeded = e => 
 
    pc1.createOffer().then(d => pc1.setLocalDescription(d)) 
 
    .then(() => pc2.setRemoteDescription(pc1.localDescription)) 
 
    .then(() => pc2.createAnswer()).then(d => pc2.setLocalDescription(d)) 
 
    .then(() => pc1.setRemoteDescription(pc2.localDescription)) 
 
    .catch(e => console.log(e));
<video id="video1" width="160" height="120" autoplay muted></video> 
 
<video id="video2" width="160" height="120" autoplay></video> 
 
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>