2015-05-20 2 views
0

Пришло время экспериментировать с WebRTC.Требуется помощь WebRTC

Я думаю, что я понимаю принцип работы, но удаленное видео черное, где моя ошибка?

Когда я добавляю консоль.log(), все в порядке, это заставляет меня сходить с ума!

Я использую Socket.io для сигнализации:

io.sockets.on('connection', function(socket) { 
    socket.on('rtcOffer', function(offer) { 
     socket.broadcast.emit('rtcOffer', offer); 
    }); 

    socket.on('rtcOfferAnswer', function(offer) { 
     socket.broadcast.emit('rtcOfferAnswer', offer); 
    }); 

    socket.on('rtcCandidate', function(candidate) { 
     socket.broadcast.emit('rtcCandidate', candidate); 
    }); 
}); 

HTML:

<video id="localVideo" width="400" autoplay="autoplay" style="border:#000 1px solid;"></video> 
<video id="remoteVideo" width="400" autoplay="autoplay" style="border:#000 1px solid;"></video> 
<button type="button" id="bCall">Call</button> 

JS:

navigator.getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia || navigator.getUserMedia; 
window.RTCPeerConnection = window.webkitRTCPeerConnection || window.mozRTCPeerConnection || window.RTCPeerConnection; 
window.createSignalingChannel = window.mozCreateSignalingChannel || window.webkitCreateSignalingChannel || window.createSignalingChannel; 
window.RTCSessionDescription = window.webkitRTCSessionDescription || window.mozRTCSessionDescription || window.RTCSessionDescription; 
window.RTCIceCandidate = window.webkitRTCIceCandidate || window.mozRTCIceCandidate || window.RTCIceCandidate; 

var _peerConn = null; 
var _mediaConstraints = { 
    mandatory : { 
     /*OfferToReceiveAudio : true,*/ 
     OfferToReceiveVideo : true 
    } 
}; 
var _rtcConfig = { 
    iceServers : [{url : 'stun:stun.ekiga.net'}, 
    {url : 'stun:stun.ideasip.com'}, 
    {url : 'stun:stun.rixtelecom.se'}, 
    {url : 'stun:stun.schlund.de'}, 
    {url : 'stun:stun.l.google.com:19302'}, 
    {url : 'stun:stun1.l.google.com:19302'}, 
    {url : 'stun:stun2.l.google.com:19302'}, 
    {url : 'stun:stun3.l.google.com:19302'}, 
    {url : 'stun:stun4.l.google.com:19302'}, 
    {url : 'stun:stun.voiparound.com'}, 
    {url : 'stun:stun.voipbuster.com'}, 
    {url : 'stun:stun.voipstunt.com'}, 
    {url : 'stun:stun.voxgratia.org'}, 
    {url : 'stun:stun.xten.com'}, 
    { 
     url : 'turn:numb.viagenie.ca', 
     credential : 'muazkh', 
     username : '[email protected]' 
    }] 
}; 

function call(localStream) { 
    _peerConn = new RTCPeerConnection(_rtcConfig, { 
     optional : [{ 
      DtlsSrtpKeyAgreement : true 
     }] 
    }); 

    _peerConn.onicecandidate = function(e) { 
     if(e.candidate) { 
      _peerConn.onicecandidate = null; 

      socketEmit('rtcCandidate', e.candidate); 
     } 
    }; 

    _peerConn.onaddstream = function(e) { 
     if(e) { 
      $('#remoteVideo')[0].src = URL.createObjectURL(e.stream); 
     } 
    }; 

    _peerConn.addStream(localStream); 

    _peerConn.createOffer(function(offer) { 
     _peerConn.setLocalDescription(new RTCSessionDescription(offer)); 

     socketEmit('rtcOffer', offer); 
    }, logError, _mediaConstraints); 
} 
function callEnd() { 
    $('video').each(function() { 
     this.pause(); 
    }); 

    _peerConn.close(); 
} 
function callAccept(localStream, offer) { 
    _peerConn = new RTCPeerConnection(_rtcConfig, { 
     optional : [{ 
      DtlsSrtpKeyAgreement: true 
     }] 
    }); 

    _peerConn.addStream(localStream); 

    _peerConn.onaddstream = function(e) { 
     if(e) { 
      $('#remoteVideo')[0].src = window.URL.createObjectURL(e.stream); 
     } 
    }; 

    _peerConn.onicecandidate = function(e) { 
     if(e.candidate) { 
      _peerConn.onicecandidate = null; 

      socketEmit('rtcCandidate', e.candidate); 
     } 
    }; 

    _peerConn.setRemoteDescription(new RTCSessionDescription(offer), function() { 
     _peerConn.createAnswer(function(answer) { 
      _peerConn.setLocalDescription(new RTCSessionDescription(answer)); 

      socketEmit('rtcOfferAnswer', answer); 
     }, logError, _mediaConstraints); 
    }, logError); 
} 
function rtcCandidateIncoming(candidate) { 
    if(_peerConn === null) { 
     setTimeout(function() { 
      rtcCandidateIncoming(candidate); 
     }, 500); 

     return; 
    } 

    _peerConn.addIceCandidate(new RTCIceCandidate({ 
     sdpMLineIndex : candidate.sdpMLineIndex, 
     candidate : candidate.candidate 
    })); 
} 
function userMediaAsk(callback) { 
    navigator.getUserMedia({ 
     video : true/*, 
     audio : true*/ 
    }, function(localStream) { 
     $('#localVideo')[0].src = window.URL.createObjectURL(localStream); 

     callback(localStream); 
    }, logError); 
} 
function logError(e) { 
    if(typeof e == typeof {}) { 
     console.log('Error : '+JSON.stringify(e)); 
    } 
    else { 
     console.log('Error : '+e); 
    } 

    callEnd(); 
} 

$(document).ready(function() { 
    $('#bCall').click(function() { 
     userMediaAsk(function(stream) { 
      call(stream); 
     }); 
    }); 

    socketRegisterSignal('rtcOffer', function(offer) { 
     userMediaAsk(function(stream) { 
      callAccept(stream, offer); 
     }); 
    }); 

    socketRegisterSignal('rtcOfferAnswer', function(answer) { 
     _peerConn.setRemoteDescription(new RTCSessionDescription(answer)); 
    }); 

    socketRegisterSignal('rtcCandidate', function(candidate) { 
     rtcCandidateIncoming(candidate); 
    }); 
}); 

window.onbeforeunload = function() { 
    if(_peerConn) { 
     _peerConn.close(); 
    } 
}; 

Большое спасибо !!

ответ

1

Я не могу точно сказать, что является причиной проблемы в вашем коде, но мой опыт заключается в том, что это вызвано из-за отсутствия кандидата на замещение льда.

Ледяные кандидаты генерируются, когда вы выполняете setLocalDecription и с тем, как PeerConnection будет стекать icecandidates с помощью метода onicecandidate, иногда удаленный одноранговый узел не готов к получению кандидатов. Я вижу таймер, который вы установили, но я бы подтвердил, что вы правильно его отправляете/получаете. Вы можете проверить состояние льда в хроме с помощью chrome: // webrtc-internalals url.

+0

Спасибо за ваш ответ, проблема была _peerConn.onicecandidate = null; при получении кандидатов, теперь все хорошо! – user3763667