WebRTC remoteVideo流无法正常工作 [英] WebRTC remoteVideo stream not working

查看:150
本文介绍了WebRTC remoteVideo流无法正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我添加了一个简单的webRTC应用程序,它将浏览器窗口连接到自身,从我的相机流式传输视频数据。最终目标是在页面上获得两个视频流,一个来自摄像头,另一个来自浏览器在本地制作的WebRTC连接。

I have added a simple webRTC application where it will connect a browser window to itself, streaming video data from the my camera. The end goal is to get two video streams on the page, one coming from the camera directly and the other coming from a WebRTC connection that the browser has made locally.

不幸的是远程视频流未显示。知道为什么吗?

Unfortunately the remote video stream is not showing up. Any idea why?

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

这里是javascript

And here's the 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);
            });
         });
    };

我正在关注Dan Ristic关于WebRTC的书,并了解他对编码的所作所为。不幸的是,远程视频没有显示。

I'm following Dan Ristic's book on WebRTC and understood what he did with the coding. Unfortunately, the remote video is not showing up.

推荐答案

添加 故障回调 让它发挥作用。不仅你不会看到错误,但这样做实际上会使它工作,这是一个非常奇怪的原因:

Add failure callbacks to make it work. Not only won't you see errors otherwise, but doing so will actually make it work, for a really weird reason:

你是一个名为WebIDL重载的东西的受害者。
正在发生的事情是有两个版本的WebRTC API,你正在混合它们。

You're a victim of something called WebIDL overloading. What's happening is there are two versions of the WebRTC API, and you're mixing them.

有一个现代承诺API ,例如:

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

已弃用的回调版本,例如:

pc.createOffer(successCallback, failureCallback, options);

换句话说,有两个 createOffer 带有不同数量参数的函数。

In other words, there are two createOffer functions that take different number of arguments.

不幸的是,你要点击第一个 createOffer ,因为你只是传递一个论点!第一个 createOffer 期望 options 对象与函数无法区分。因此它被视为有效参数(空选项对象)。即使这导致了 TypeError ,也不会导致异常,因为promise API会拒绝返回的promise而不是抛出异常:

Unfortunately, you're hitting the first createOffer because you're only passing one argument! The first createOffer expects an options object which unfortunately in WebIDL is indistinguishable from a function. It is therefore treated as a valid argument (an empty options object). Even if this had caused a TypeError, it wouldn't have caused an exception, because promise APIs reject the returned promise instead of throwing an exception:

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

您也没有检查返回的保证,因此错误会丢失。

You're not checking the returned promise either, so errors are lost.

这是一个工作版本( https小提琴对于Chrome):

Here's a working version (https fiddle for 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>

但回调很费力。我强烈推荐使用新的promise API( https for Chrome):

But callbacks are laborious. I highly recommend the new promise API instead (https for 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>

这篇关于WebRTC remoteVideo流无法正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆