• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

WebRTC remoteVideo流没办法正常工作

用户头像
it1352
帮助1

问题说明

我添加了一个简单的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   autoplay></video>
<video   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.谷歌.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.

正确答案

#1

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

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.谷歌.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       autoplay></video>
<video       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       autoplay muted></video>
<video       autoplay></video><br>
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /reply/detail/tanhcfggcg
系列文章
更多 icon
同类精品
更多 icon
继续加载