使用 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 访问视频。
到目前为止,我尝试了哪些流式传输网络摄像头:
- 使用 OBS 流式传输 udp、rtp 和 srt url:
- 协议://145.89.161.93:8087?mode=listener
- 协议://127.0.0.1:8087?mode=listener
- 协议://145.89.161.93:8087
- 协议://145.89.161.93:8087
- 使用 vlc 媒体播放器流式传输 http、rtsp、rtp、udp。
我已经尝试在 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()
命令。或者您可以在浏览器的设置中启用自动播放,视频将自动开始播放。
我目前正在进行一个项目,我在 VR 中控制机器人手臂。我正在使用 A-Frame 和 oculus quest 1 进行此操作。 为了让用户看到他们正在用机器人手臂做什么,我想将指向手臂的网络摄像头的视频流式传输到 Web-VR 应用程序。网络摄像头和耳机都在同一个 LAN 上,所以我不需要可以从 Internet 访问视频。
到目前为止,我尝试了哪些流式传输网络摄像头:
- 使用 OBS 流式传输 udp、rtp 和 srt url:
- 协议://145.89.161.93:8087?mode=listener
- 协议://127.0.0.1:8087?mode=listener
- 协议://145.89.161.93:8087
- 协议://145.89.161.93:8087
- 使用 vlc 媒体播放器流式传输 http、rtsp、rtp、udp。
我已经尝试在 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 theGET
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()
命令。或者您可以在浏览器的设置中启用自动播放,视频将自动开始播放。