使用 LAN 网络摄像头流作为 A-Frame 中的视频源

Use LAN webcam stream as a source for a-video in A-Frame

我目前正在进行一个项目,我在 VR 中控制机器人手臂。我正在使用 A-Frame 和 oculus quest 1 进行此操作。 为了让用户看到他们正在用机器人手臂做什么,我想将指向手臂的网络摄像头的视频流式传输到 Web-VR 应用程序。网络摄像头和耳机都在同一个 LAN 上,所以我不需要可以从 Internet 访问视频。

到目前为止,我尝试了哪些流式传输网络摄像头:

我已经尝试在 vlc 中观看所有 obs 流,唯一似乎有效的是带有 mode=listener 的 srt 流。但是当我试图在框架中查看该流时,我没有工作。 现在 obs 不再让我使用 srt 进行流式传输(我不知道为什么)。我会尝试重新安装 obs 看看是否有帮助。

我尝试在 A-Frame 中查看流:

<a-video  src="protocol://145.89.161.93:8087" width="16" height="9" position="0 0 -10"></a-video>
<a-assets>
    <video id="#webcam_stream" src="protocol://145.89.161.93:8087" playsinline> </video>
</a-assets>

<a-video  src="#webcam_stream" width="16" height="9" position="0 0 -10"></a-video>

http 流似乎无法正常工作,因为 Oculus 连接的服务器 运行 使用 https。否则耳机将不允许使用 VR。对于其他流,A-Frame 似乎不会在连接或未知源文件等方面出现错误。但它也不显示 stream/video。

其他 VLC 流出现跨源错误,但当我使用 crossorigin="anonymous" 时,该错误消失了。但是如果我这样做,a-video 组件找不到#webcam_stream 资产。

我认为 this 教程会有所帮助,即使它不是框架。但是 html 代码不可见,所以它不是很有用。

我对网络开发和流媒体的主题不是很了解,但这是我们项目的重要组成部分。因此,我们将不胜感激。

如果有人有办法在 A-Frame 中显示远程网络摄像头流、预先存在的代码或要研究的一般 direction/suggestion,我们将不胜感激。

好的,经过大量查找,我找到了解决问题的方法! 我必须解决多个问题:

  • html5 仅支持有限数量的流媒体协议
  • 流必须是安全的,因为 VR 应用程序是使用 https
  • 托管的
  • 我们需要将视频应用于 A-Frame 中的实体
  • 我们需要开始实际的直播。
  • 我们几乎不需要延迟

流媒体协议

对于我最终使用的流媒体协议 HLS. It is not supported by most browsers and HTML5 by default. But but with usage of HLS.js 我们可以很容易地添加这种支持。

安全

使用此协议还可以解决我们的安全问题。由于 HLS 流基本上只是使用 HTTP/HTTPS 服务器提供的短视频片段。因为我们的服务器是一个简单的https服务器,所以我们只需要将HLS文件输出到服务器内部的一个目录下,让应用程序可以使用。

如果您的流与您的应用程序不在同一台服务器上,您将需要通过 HLS.js 库

添加 CORS Headers to your HLS Host for the GET request. This is a requirement

在 A 帧中的实体上应用视频

要将流应用于 A-Frame 中的实体,我们需要一个 <video> 资产。加载此资产后,我们可以使用脚本在资产上应用流。然后我们可以将此资产用作实体和纹理的来源。

下面的代码正是这样做的。由于实体在资产之后加载,向 <a-video> 实体添加组件将在资产加载后调用脚本。然后我们可以将资产用作 <a-video> 实体的源.

<!DOCTYPE html>
<html>
    <head>
        <script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
        <script src="hls.js"></script>
        <script>
            AFRAME.registerComponent('hls_stream', {
                init: function(){
                    var video = document.getElementById('webcam_stream');
                    if(Hls.isSupported()) {
                    var hls = new Hls();
                    hls.loadSource('https://ip:port/path_to_hls_file/filename.m3u8');
                    hls.attachMedia(video);
                    hls.on(Hls.Events.MANIFEST_PARSED,function() {
                        video.play();
                    });
                }
                else if (video.canPlayType('application/vnd.apple.mpegurl')) {
                    video.src = 'https://ip:port/path_to_hls_file/filename.m3u8';
                    video.addEventListener('loadedmetadata',function() {
                        video.play();
                    });
                    }
                }
            })
          </script>
    </head>   
    <body>
        <a-scene cursor="rayOrigin:mouse">
            <a-assets>
                <video id="webcam_stream" crossorigin="anonymous"></video>
            </a-assets>

            <a-video src="#webcam_stream" width="16" height="9" position="0 4.5 -20" hls_stream></a-video>

          
            <a-entity id="camera"  wasd-controls camera look-controls></a-entity>
            <a-sky color="#111"></a-sky>
        </a-scene>
    </body>
</html>

如何直播

目前我正在使用 OBS. You can find how to stream HLS using OBS here 创建 HLS 流 OBS 相对容易设置,并且允许的不仅仅是网络摄像头,因为您可以使用 OBS 捕获几乎任何视频、屏幕或其他输入源。

延迟

我唯一还在苦恼的是OBS流的延迟。因为有2秒的segment,并且因为OBS的HLS流的segment list的长度是4,所以我们通常会得到8秒左右的延迟。这仍然比我想要的要大,但它现在可以做,因为启动低延迟 HLS 流是另一个问题的主题。

开始播放

大多数浏览器默认禁用视频文件的自动播放。因此,如果自动播放被禁用,您将需要手动启动 video.play() 命令。或者您可以在浏览器的设置中启用自动播放,视频将自动开始播放。