Le flux de RemoteVideo WebRTC ne fonctionne pas

J'ai ajouté une simple application webRTC où il va se connecter une fenêtre de navigateur à elle-même, en streaming de données vidéo de la caméra. L'objectif final est d'obtenir deux flux vidéo sur la page, l'un provenant directement de l'appareil photo et l'autre provenant d'une connexion WebRTC que le navigateur a localisée.

Malheureusement, le flux vidéo à distance ne s'affiche pas. Une idée pourquoi?

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

Et voici le 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); }); }); }; 

Je suis en train de suivre le livre de Dan Ristic sur WebRTC et j'ai compris ce qu'il a fait avec le codage. Malheureusement, la vidéo à distance ne s'affiche pas.

Ajoutez des rappels d'échec pour le faire fonctionner. Non seulement vous ne verrez pas les erreurs autrement, mais ce faisant, cela fonctionnera réellement, pour une raison vraiment étrange:

Vous êtes une victime de quelque chose d'appelé surchargement WebIDL. Ce qui se passe, il y a deux versions de l'API WebRTC, et vous les mélangez.

Il existe une API prometteuse moderne , par exemple:

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

Et une version de rappel refusée , par exemple:

 pc.createOffer(successCallback, failureCallback, options); 

En d'autres termes, il existe deux fonctions createOffer qui prennent différents nombres d'arguments.

Malheureusement, vous createOffer le premier createOffer parce que vous ne faites qu'un seul argument! Le premier createOffer s'attend à un objet d' options qui, malheureusement, dans WebIDL est indistinguable d'une fonction. Il est donc traité comme un argument valide (un objet d'options vide). Même si cela avait causé un TypeError , il n'aurait pas provoqué d'exception, car les API prometteuses rejettent la promesse retournée au lieu de lancer une exception:

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

Vous ne vérifiez pas non plus la promesse de retour, donc les erreurs sont perdues.

Voici une version de travail ( https violon pour 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>