将WebRTC与Socket.io一起使用

将WebRTC与Socket.io一起使用,socket.io,webrtc,Socket.io,Webrtc,我正在尝试创建一个用于在浏览器中进行音频通话的应用程序。我找到了本教程并开始使用它作为基础: 经过一些调整以满足我的需要。我的结论如下: var iceServers = [ { url: 'stun:stun1.l.google.com:19302' }, { url: 'turn:numb.viagenie.ca', credential: 'muazkh', username: 'webrtc@live.com' } ]; var sdpConstraints = {

我正在尝试创建一个用于在浏览器中进行音频通话的应用程序。我找到了本教程并开始使用它作为基础:

经过一些调整以满足我的需要。我的结论如下:

var iceServers = [
    { url: 'stun:stun1.l.google.com:19302' },
    { url: 'turn:numb.viagenie.ca', credential: 'muazkh', username: 'webrtc@live.com' }
];

var sdpConstraints = {
    optional: [],
    mandatory: {
        OfferToReceiveAudio: true,
        OfferToReceiveVideo: false
    }
};

var DtlsSrtpKeyAgreement = {
   DtlsSrtpKeyAgreement: true
};

var optional = {
   optional: [DtlsSrtpKeyAgreement]
};


var peer = new webkitRTCPeerConnection({
    'iceServers': iceServers,
    optional
});


function getAudio(successCallback, errorCallback){

    navigator.webkitGetUserMedia(
      {
        audio: true, 
        video: false
      },
      successCallback,
      errorCallback
    );

}


function send_SDP() {
    console.log('now emitting send sdp message');
    SocketService.emit('message', {
        'conversation_id': me.conversation_id,
        'targetUser': to,
        'sdp': peer.localDescription
    });
}


function startCall(){

    getAudio(
        function(stream){

            console.log('peer');
            console.log(peer);

            console.log('adding local stream');
            peer.addStream(stream);

            peer.createOffer(function(offerSDP) {
                console.log('now creating offer');
                peer.setLocalDescription(offerSDP, function(){
                    console.log('local description is set. now informing peer');

                    SocketService.emit('message', {
                        'conversation_id': me.conversation_id,
                        'targetUser': to,
                        'offerSDP': offerSDP
                    });
                },
                function(){
                    console.log('error setting local description')
                });
                console.log('now emitting offerSDP message');
            }, 
            function(){
                console.log('error occured while creating offer');
            }, 
            sdpConstraints
            );


            console.log('now calling ' + to);

        },
        function(err){
            console.log('an error occured while getting the audio');
        }
    );


};


function createAnswer(offerSDP) {

    getAudio(
        function(stream){
            console.log('now creating answer');
            console.log(stream);

            console.log('NOW ADDING STREAM');
            peer.addStream(stream);

            var remoteDescription = new RTCSessionDescription(offerSDP);
            peer.setRemoteDescription(remoteDescription);

            peer.createAnswer(function(answerSDP) {
                peer.setLocalDescription(answerSDP, function(){
                    console.log('done setting local description');
                    console.log('now emitting answer sdp message');
                    SocketService.emit('message', {
                        'conversation_id': me.conversation_id,
                        'targetUser': to,
                        'answerSDP': answerSDP
                    });
                },
                function(){
                    console.log('error setting local description');
                });
            }, function(err){
                alert('error occured while creating answer');
                console.log(err);
            }, sdpConstraints);

        },
        function(err){
            alert('error occured while getting the audio for answer');
        }
    );

};


SocketService.on('message', function(msg){

    if(msg.offerSDP){

        var remoteDescription = new RTCSessionDescription(msg.offerSDP);
        peer.setRemoteDescription(remoteDescription, function(){
            console.log('done setting remote description');
            createAnswer(msg.offerSDP);
        },
        function(){
            console.log('error setting remote description');
        });

    }

    if(msg.answerSDP) {
        var remoteDescription = new RTCSessionDescription(msg.answerSDP);
        peer.setRemoteDescription(remoteDescription, function(){
            console.log('finished signaling offers and answers!');
        },
        function(){
            console.log('error signaling offers and answers');
        });
    }


    if(msg.candidate) {

        var candidate = msg.candidate.candidate;
        var sdpMLineIndex = msg.candidate.sdpMLineIndex;

        peer.addIceCandidate(new RTCIceCandidate({
            sdpMLineIndex: sdpMLineIndex,
            candidate: candidate
        }));
    }


});


peer.onaddstream = function(stream){
    console.log('now adding remote stream');
    console.log(stream);
    audio.src = window.URL.createObjectURL(stream); //this is where the error occurs
};      


peer.onicecandidate = function(event) {
    console.log('on ice candidate');
    var candidate = event.candidate;
    console.log(candidate);
    console.log('after ice candidate');
    if(candidate) {
        console.log('now emitting candidate message');
        SocketService.emit('message', {
            'conversation_id': me.conversation_id,
            'targetUser': to,
            'candidate': candidate
        });
    }

    console.log(typeof candidate);
    if(typeof candidate == 'undefined') {
        console.log('now sending sdp');
        send_SDP();
    }

};


peer.ongatheringchange =  function(e) {
    if (e.currentTarget && e.currentTarget.iceGatheringState === 'complete') {
        send_SDP();
    }
};
这里发生的事情是,首先在单击调用按钮时调用
startCall
方法。这会触发浏览器请求访问网络摄像头和麦克风。一旦用户接受它,就会使用
addStream
方法添加本地流。之后,将创建一个报价并设置本地描述。然后,我使用socket.io向对等方发送消息以发送报价。收到要约后,使用通过socket.io发送的要约DP设置远程rtc会话描述。一旦完成,答案就开始了。这将触发浏览器请求网络摄像头和麦克风。此时,错误发生在接收呼叫的对等方。然后将流添加到对等方。然后设置会话描述,对等方创建一个答案。完成后,将设置本地描述,并将包含答案的消息发送给呼叫对等方。然后设置会话描述并最终确定信令部分。此时,错误发生在调用的对等方上

但是,每当我到达添加来自另一个对等方的远程流的部分时,就会出现以下错误

未能对“URL”执行“createObjectURL”:未找到与提供的签名匹配的函数


有什么想法吗?

peer.onaddstream
不是用流激发的,而是用包含流的事件对象激发的:

更改此项:

peer.onaddstream = function(stream){
    console.log('now adding remote stream');
    console.log(stream);
    audio.src = window.URL.createObjectURL(stream);
};  
为此:

peer.onaddstream = function(event){
    console.log('now adding remote stream');
    console.log(event);
    console.log(event.stream);
    audio.src = window.URL.createObjectURL(event.stream);
}; 

传递给
createObjectUrl
stream
的值是多少?你确定这是一个流吗?你已经在哪个浏览器上运行了测试?@ObscureGeek我主要在Ubuntu中使用Chrome和Chrome@是的,这是一条小溪。我使用了
console.log
check@Kyokasuigetsu由于您仅在Chrome和Chrome上进行测试,因此尝试使用
webkitURL.createObjectURL(stream)?是的,它说它已经被弃用了。如果我使用了
URL.createObjectURL
,我认为它会退回到使用
URL.createObjectURL。然后我得到了同样的错误