2016-07-09 4 views
1

Я добавил простое приложение webRTC, где оно подключит окно браузера к себе, потоковое видео данных с моей камеры. Конечной целью является получение двух видеопотоков на странице, один из которых поступает с камеры напрямую, а другой - из соединения WebRTC, которое браузер сделал локально.WebRTC remoteVideo поток не работает

К сожалению, удаленный видеопоток не отображается. Любая идея почему?

<video id="yours" autoplay></video> 
<video id="theirs" autoplay></video> 

И вот Javascript

function hasUserMedia() { 
    navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || 
     navigator.msGetUserMedia; 

    return !!navigator.getUserMedia; 
    } 

    function hasRTCPeerConnection() { 
    window.RTCPeerConnection = window.RTCPeerConnection || window.webkitRTCPeerConnection 
     || window.mozRTCPeerConnection; 

    return !!window.RTCPeerConnection; 
    } 

    var yourVideo = document.querySelector('#yours'), 
    theirVideo = document.querySelector('#theirs'), 
    yourConnection, theirConnection; 


    if (hasUserMedia()) { 
     navigator.getUserMedia({ video: true, audio: false }, function(stream) { 
     yourVideo.src = window.URL.createObjectURL(stream); 
     if (hasRTCPeerConnection()) { 
      startPeerConnection(stream); 
     } else { 
     alert("Sorry, your browser does not support WebRTC."); 
     } 
     }, function (error) { 
     console.log(error); 
     }); 
     }else{ 
      alert("Sorry, your browser does not support WebRTC."); 
     } 


    function startPeerConnection(stream){ 
     var configuration = { 
      "iceServers": [{ "url": "stun:stun.1.google.com:19302" 
      }] 
     }; 

     yourConnection = new RTCPeerConnection(configuration); 
     theirConnection = new RTCPeerConnection(configuration); 



     // Setup stream listening 
     yourConnection.addStream(stream); 

     theirConnection.onaddstream = function (event) { 
      theirVideo.src = window.URL.createObjectURL(event.stream); 
      console.log('stream added'); 
     }; 

     // console.log(yourConnection); 
      //console.log(theirConnection); 

     // Setup ice handling 
     yourConnection.onicecandidate = function (event) { 
     if (event.candidate) { 
       theirConnection.addIceCandidate(new RTCIceCandidate(event. 
       candidate)); 
      } 
     }; 
     theirConnection.onicecandidate = function (event) { 
      if (event.candidate) { 
       yourConnection.addIceCandidate(new RTCIceCandidate(event. 
       candidate)); 
      } 
     }; 

      // Begin the offer 
     yourConnection.createOffer(function (offer) { 
      yourConnection.setLocalDescription(offer); 
      theirConnection.setRemoteDescription(offer); 

      theirConnection.createAnswer(function (offer) { 
       theirConnection.setLocalDescription(offer); 
       yourConnection.setRemoteDescription(offer); 
      }); 
     }); 
    }; 

Я следую за книгу Дэна Ristić на WebRTC и понял, что он сделал с кодировкой. К сожалению, удаленное видео не отображается.

ответ

4

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

Вы жертвой чего-то перегруженного WebIDL. Что происходит, есть две версии API WebRTC, и вы их смешиваете.

Там в modern promise API, например .:

pc.createOffer(options).then(successCallback, failureCallback); 

и deprecated callback version и т.д .:

pc.createOffer(successCallback, failureCallback, options); 

Другими словами, есть две createOffer функции, которые принимают разное количество аргументов.

К сожалению, вы попали в первый createOffer, потому что вы передаете только один аргумент! Первый createOffer ожидает объект options, который, к сожалению, в WebIDL неотличим от функции. Поэтому он рассматривается как допустимый аргумент (пустой объект опций). Даже если бы это вызвало TypeError, это не вызвало бы исключение, потому что обещание API, отклонить возвращаемый обещание, а не бросать исключение:

pc.createOffer(3).catch(e => console.log("Here: "+ e.name)); // Here: TypeError 

Вы не проверяя возвращаемый обещание либо, поэтому ошибки потерял.

Вот рабочая версия (https fiddle для Chrome):

navigator.getUserMedia = navigator.getUserMedia || 
 
         navigator.webkitGetUserMedia || 
 
         navigator.mozGetUserMedia; 
 
window.RTCPeerConnection = window.RTCPeerConnection || 
 
          window.webkitRTCPeerConnection; 
 

 
var yourConnection, theirConnection; 
 

 
navigator.getUserMedia({ video: true, audio: false }, function(stream) { 
 
    yourVideo.src = window.URL.createObjectURL(stream); 
 

 
    var config = { "iceServers": [{ "urls": "stun:stun.1.google.com:19302"}] }; 
 
    yourConnection = new RTCPeerConnection(config); 
 
    theirConnection = new RTCPeerConnection(config); 
 

 
    yourConnection.addStream(stream); 
 

 
    theirConnection.onaddstream = function (event) { 
 
     theirVideo.src = window.URL.createObjectURL(event.stream); 
 
    }; 
 

 
    yourConnection.onicecandidate = function (e) { 
 
     if (e.candidate) { 
 
      theirConnection.addIceCandidate(new RTCIceCandidate(e.candidate), 
 
              success, failure); 
 
     } 
 
    }; 
 
    theirConnection.onicecandidate = function (e) { 
 
     if (e.candidate) { 
 
      yourConnection.addIceCandidate(new RTCIceCandidate(e.candidate), 
 
              success, failure); 
 
     } 
 
    }; 
 

 
    yourConnection.createOffer(function (offer) { 
 
     yourConnection.setLocalDescription(offer, success, failure); 
 
     theirConnection.setRemoteDescription(offer, success, failure); 
 
     theirConnection.createAnswer(function (offer) { 
 
      theirConnection.setLocalDescription(offer, success, failure); 
 
      yourConnection.setRemoteDescription(offer, success, failure); 
 
     }, failure); 
 
    }, failure); 
 
}, failure); 
 

 
function success() {}; 
 
function failure(e) { console.log(e); };
<video id="yourVideo" width="160" height="120" autoplay></video> 
 
<video id="theirVideo" width="160" height="120" autoplay></video>

Но обратные вызовы являются трудоемкими. Я настоятельно рекомендую новое обещание API вместо (https для Chrome):

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

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

 
var add = (pc, can) => pc.addIceCandidate(can).catch(log); 
 
pc1.onicecandidate = e => add(pc2, e.candidate); 
 
pc2.onicecandidate = e => add(pc1, e.candidate); 
 

 
pc2.ontrack = e => video2.srcObject = e.streams[0]; 
 
pc1.oniceconnectionstatechange = e => 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(log); 
 

 
var log = msg => console.log(msg);
<video id="video1" height="120" width="160" autoplay muted></video> 
 
<video id="video2" height="120" width="160" autoplay></video><br> 
 
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>

+1

Woww. Этот ответ сделал мой день. Я новичок в WebRTC, и я буду вас очень беспокоить в будущем! – marukobotto

+0

Я не понимаю. Я много понимаю, но все равно не понимаю. Этот пример должен установить соединение с одноранговым узлом. Поэтому во втором «видео» я должен видеть кого-то другого, а не меня, верно? –

+0

@ DamianHetman, кого вы ожидали увидеть?:) Это демонстрация только локального цикла. Для реального вызова вам нужно знать, с кем звонить, и какой-либо канал сигнализации для обмена предложением/ответом для настройки вызова. – jib

Смежные вопросы