Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/416.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何抽象WebRTC产品?_Javascript_Sockets_Stream_Webrtc_Getusermedia - Fatal编程技术网

Javascript 如何抽象WebRTC产品?

Javascript 如何抽象WebRTC产品?,javascript,sockets,stream,webrtc,getusermedia,Javascript,Sockets,Stream,Webrtc,Getusermedia,我在WebRTC的报价生成过程的抽象方面遇到了一个奇怪的问题。似乎传入的ice候选者从未到达空候选者。在使用几乎相同的代码之前,我已经成功地生成了报价,但无论出于何种原因,我的抽象版本仅达到12个候选版本,而我的原始版本通常只有20个。这太奇怪了,代码看起来几乎一样,但抽象的代码甚至在同一个浏览器上都不起作用 原始工作代码: var localConn = new webkitRTCPeerConnection({'iceServers':[{...}]}); var remot

我在WebRTC的报价生成过程的抽象方面遇到了一个奇怪的问题。似乎传入的ice候选者从未到达空候选者。在使用几乎相同的代码之前,我已经成功地生成了报价,但无论出于何种原因,我的抽象版本仅达到12个候选版本,而我的原始版本通常只有20个。这太奇怪了,代码看起来几乎一样,但抽象的代码甚至在同一个浏览器上都不起作用

原始工作代码:

    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);
                }  
            }
        }
    }
具有用于抽象的函数的新版本(不获取空ice候选)

您的
createOffer
函数和您的
initStream
函数之间可能存在一场竞赛,因为当您计算它们启动的所有内容时,这两个函数实际上是异步的(很难确定,因为您没有显示该代码)

如果您想抽象WebRTC,您应该考虑摆脱旧的遗留API,而使用RTPeerConnection的。在处理这样的种族问题时,承诺比回调更具抽象性

也可以考虑使用<代码>需要协商< <代码>回调来触发协商,以解决这个问题(但是要小心)。 下面是一个本地连接示例(在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=>
然后(d=>pc1.setLocalDescription(d))
.then(()=>pc2.setRemoteDescription(pc1.localDescription))
。然后(()=>pc2.createAnswer())。然后(d=>pc2.setLocalDescription(d))
.then(()=>pc1.setRemoteDescription(pc2.localDescription))
.catch(e=>console.log(e))

您的
createOffer
函数和您的
initStream
函数之间可能存在一场竞赛,因为当您计算它们启动的所有内容时,这两个函数实际上是异步的(很难确定,因为您没有显示该代码)

如果您想抽象WebRTC,您应该考虑摆脱旧的遗留API,而使用RTPeerConnection的。在处理这样的种族问题时,承诺比回调更具抽象性

也可以考虑使用<代码>需要协商< <代码>回调来触发协商,以解决这个问题(但是要小心)。 下面是一个本地连接示例(在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=>
然后(d=>pc1.setLocalDescription(d))
.then(()=>pc2.setRemoteDescription(pc1.localDescription))
。然后(()=>pc2.createAnswer())。然后(d=>pc2.setLocalDescription(d))
.then(()=>pc1.setRemoteDescription(pc2.localDescription))
.catch(e=>console.log(e))


我可以问一下,您基于哪个示例编写此代码吗?它使用了非常古老的构造,比如传统的回调API,并且只在启动时与Chrome浏览器一起工作,因为webkit前缀(我正试图追踪旧的示例来更新它们)。stun:stun.1.google.com:19305不是一个stun服务器。您可能想使用stun:stun.l.google.com:19305进行测试,我可以问一下您基于哪个示例编写此代码吗?它使用了非常古老的构造,比如传统的回调API,并且只在启动时与Chrome浏览器一起工作,因为webkit前缀(我正试图追踪旧的示例来更新它们)。stun:stun.1.google.com:19305不是一个stun服务器。你可能想用stun:stun.l.google.com:19305进行测试
//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
    }
}
streamHandle(stream);    //gets inserted into createOffer function