使用 RICOH THETA 相机将 360 度视频流式传输到 VR 头显
将来自飞行无人机的 360 度视频实时流式传输到 VR 头显,例如 Oculus Rift 或 HTC Vive
360 度视频流和无人机
无人机被广泛用于工业监控和娱乐,但无法在 Oculus Rift 或 HTC Vive 等 VR 头显中提供沉浸式体验。
沉浸式体验的大部分问题源于使用多个摄像头,这些摄像头可以覆盖无人机的整个全景视野,但当人们在 VR 头显中转头时,无法准确跟踪场景。
为了解决这个问题,Jake Kenin 使用 RICOH THETA V 将视频直播到地面站和 VR 头显。
技术
视频技术
Jake 的解决方案使用 MotionJPEG。这是一种妥协。使用 MotionJPEG 导致分辨率和帧率低于其他技术。虽然相机本身可以以 3840x1920、30fps 的速度传输,但 Jake 目前的解决方案在 0.25 英里的距离上具有以下性能:
- 在 1920x960 @ 8fps 下约为 250 毫秒的延迟
- 在 1024x512 @ 30 fps 下约为 100 毫秒的延迟
延迟是指图像在头显中显示所需的时间。 例如,如果您使用控制器移动无人机,您将在大约 1/5 秒后看到移动变化。 您希望延迟尽可能低。 如果延迟太长,将很难驾驶无人机。
当您在头显中观看 360 度视频时,您无法看到整个视频。 大约 2/3 的视频被隐藏。 您转动头部以查看视频的隐藏部分。 1024 像素的视频看起来像 400 像素的视频。
fps 指的是每秒帧数,通常称为帧率。 帧率越高,视频越流畅。 在 8fps 时,视频会明显卡顿。
Jake 测试了其他传输技术,例如 RTMP 和 RTSP,而不是 MotionJPEG
。 虽然分辨率和帧率更好,但延迟大于 1 秒,使得无人机难以高速飞行。
由于 MotionJPEG 的限制,Jake 计划使用高压缩视频标准将其项目适配到 4K 视频。
查看器技术
为了将视频流显示到 Oculus Rift 头显中,Jake 使用了带有 NPM 应用程序的 Electron 来提供 OpenVR 绑定。
Jake 还使用了 A-Frame 来实现 VR 功能。
安装技术
为了稳定视频流,Jake 使用了万向节。
获取代码和构建详细信息
构建的详细信息可以在论坛上的一系列 community.theta360.guide 上的帖子中找到。
Jake 编写的 Amelia Viewer 的查看器代码可在 GitHub 上找到。
此项目的零件如下所示
由于 MotionJPEG 是一种流,因此您需要读取字节流并显示它。 视频的每一帧都是一张 JPEG 图像。 这是许多开发人员处理实时视频流最困难的部分。 有许多 JavaScript 示例可以读取 bytestream
。 这是 Jake 的做法。
const read = () => {
reader.read().then(({done, value}) => {
if (done) {
return;
}
for (let index =0; index < value.length; index++) {
// Start of the frame, everything we've till now was header
if (value[index] === SOI[0] && value[index+1] === SOI[1]) {
contentLength = getLength(headers);
imageBuffer = new Uint8Array(
new ArrayBuffer(contentLength));
}
// we're still reading the header.
if (contentLength <= 0) {
headers += String.fromCharCode(value[index]);
}
// we're now reading the jpeg.
else if (bytesRead < contentLength){
imageBuffer[bytesRead++] = value[index];
bytesThisSecond++;
}
// we're done reading the jpeg. Time to render it.
else {
//console.log("jpeg read with bytes : " + bytesRead);
// Generate blob of the image and emit event
lastFrameImgUrl = URL.createObjectURL(
new Blob([imageBuffer], {type: TYPE_JPEG}));
var reRenderEvent = new CustomEvent(RERENDER_EVENT,
{ detail: lastFrameImgUrl });
document.dispatchEvent(
reRenderEvent);
// Reset for the frame
frames++;
contentLength = 0;
bytesRead = 0;
headers = '';
}
}
完整的代码位于他的 GitHub 仓库的这个文件中。
社区认可
Jake 解决了社区已经研究了 3 年的问题。 他赢得了 他成功的项目月度奖。
飞行无人机的变化
Jake 的概念类似于 Hugues Perret 的 Fox Sewer Rover。
FOX SEWER ROVER 项目的传输代码可在此处找到:here。
在 Raspberry Pi 上测试
Hugues 的代码是用 Python 编写的,可以在 Raspberry Pi 上运行。 如果您想在汽车上试验无人机,这是一个不错的选择。
加入先驱讨论
还有很多事情要做和探索。 这个领域确实处于新生状态。 爱好者有可能取得突破和做出贡献。 如果您有任何问题、意见或贡献,请随时将它们放入我们用作平台的 RICOH THETA 360 相机的开发社区论坛中。