将WebRTC与Socket.io一起使用

时间:2015-06-22 08:59:10

标签: socket.io webrtc

我正在尝试创建一个用于在浏览器中拨打音频的应用。我找到了本教程并开始使用它作为基础:https://www.webrtc-experiment.com/docs/WebRTC-PeerConnection.html

经过一些调整以满足我的需求。我最终得到了以下内容:

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发送的offerSDP设置远程rtc会话描述。完成后,即可启动答案。这将触发浏览器请求网络摄像头和麦克风。此时,错误发生在接收呼叫的对等方。然后将流添加到对等体。然后设置会话描述,并且对等体创建答案。完成后,将设置本地描述,并将包含答案的消息发送给主叫对等方。然后设置会话描述并最终确定信令部分。此时,调用对等体发生错误。

但是每当我到达从其他对等方添加远程流的部分时,我都会收到以下错误。

Failed to execute 'createObjectURL' on 'URL': No function was found that matched the signature provided

有什么想法吗?

1 个答案:

答案 0 :(得分:2)

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);
};