基于 WebRTC 和 WebVR 实现 VR 视频通话

 文章转载自 WebRTC 中文网,原作者Dan Jenkin

Web 平台上的 WebRTC 并不是其唯一的媒体 API。WebVR 说明书于几年前被引入来为浏览器中的虚拟现实设备提供支持。目前已经变为新的 WebXR设备API说明书

Dan Jenkin 说使用 WebVR、FreeSWITCH 向虚拟现实环境中添加一个 WebRTC 视频会议流是相对简单的。FreeSWITCH 是一个流行的开源电话平台,并且已经拥有 WebRTC 有几年时间了。

Dan 是一个 Google 开发专家,他喜欢讲将最新的 Web API 和 RTC App 结合起来. 以下文章给出了他的代码来说明他是如何使用 WebVR 将 FreeSWITCH Verto WebRTC 视频会议转变成虚拟现实会议的。

01

几周之前,我参加了一个关于 WebRTC 和 WebVR 的活动。将VR内容加入你的浏览器和移动电话会增加 App 的潜力,吸引跟多人。在过去的两三年内,伴随着 Google 的 Cardboard,VR对于手机来说已经可以负担得起,并被广泛使用,同时 Oculus Go 完全不需要移动设备。我想探索对于 App 如何在 WebRTC 媒体中使用这种新的廉价媒介。

事实上,在向 Call For Papers 上传讨论之前我对于 WebVR 并没有任何头绪,但是我知道在看到其它演示之后我可能有所收获。我认为只需要勇敢向前,上传一段疯狂的讨论,并看看有谁认同。

A-Frame 框架

开始WebVR有几种方法,我选择使用一个叫做A-Frame的框架,它允许我写入一些HTML并引入 JavaScript库,直接建立VR体验。尽管演示不像我期待的那样,但是这说明你确实可以用很少的代码实现令人惊讶的VR体验。

如果你熟悉Web组成,你会直接知道A-Frame在做什么。现在,你可能会问为什么我会用它而不是直接使用WebGL,WebVR polyfill和Three.js来创建WebGL对象或者另外一种框架。简单来说,我喜欢少写代码,A-Frame看起来满足这一点。

如果你不喜欢A-Frame,你可以试试其它选择,例如webvr.info上的React360.

使用WebRTC建立WebVR体验

如今使用A-Frame可以实现多种WebRTC VR体验。Mozilla 团队实现了一种,在VR场景中,用户可以相互看到用点表示的对方,并且可以听到对方的声音。他们使用WebRTC Data Channels 和WebRTC Audio实现了这个过程,但是我并不能找到任何使用了WebRTC视频的地方,因此引出了一个如何在3D环境中使用实时视频的挑战。

我的演示基于开源FreeSWITCH Verto Communicator。Verto使用了WebRTC,并且我已经知道如何在FreeSWITCH中使用Verto客户端库与Verto组件交流,因此已经完成了一半的挑战。Verto客户端库是发信部分—替换Websocket上的SIP,将SIP PBX与WebRTC断点连接。

HTML

请查看我向Verto Communicator中添加的A-Frame代码,一共只有8行。


首先a-scene元素创建了一个场景,包含了VR体验中所有过程,空的a-assets标签用来放入我们的WebRTC视频标签。

下一行a-entity是使用户沉浸的简单体验中最重要的一行。它是一个a-frame整体,具有预先配置的环境,将整体体验分步。

其它的entities负责摄像头和幻想控制。查看建立3D形状和对象时,你可以用的A-frame中支持的组件

这些只是将场景集合起来,接下来我们建立控制逻辑代码,使用 JavaScript.

JavaScript

Verto Communicator是一个angular based的App,因此元素可以被加入或移出主应用空间。我们需要一些逻辑来连接Verto和A-frame。这个逻辑所需代码不到40行

function link(scope, element, attrs) {

  var newVideo = document.createElement('a-video');
  newVideo.setAttribute('height', '9');
  newVideo.setAttribute('width', '16');
  newVideo.setAttribute('position', '0 5 -15');
  console.log('ATTACH NOW');
  var newParent = document.getElementsByClassName('video-holder');
  newParent[0].appendChild(newVideo);

  window.attachNow = function(stream) {
    var video = document.createElement('video');

    var assets = document.querySelector('a-assets');

    assets.addEventListener('loadeddata', () => {
      console.log('loaded asset data');
    })

    video.setAttribute('id', 'newStream');
    video.setAttribute('autoplay', true);
    video.setAttribute('src', '');
    assets.appendChild(video);

    video.addEventListener('loadeddata', () => {
      video.play();

      // Pointing this aframe entity to that video as its source
      newVideo.setAttribute('src', `#newStream`);
    });

    video.srcObject = stream;
  }
复制代码

当你使用Verto Communicator app进入会议界面时,以上Link函数被安装。

修改Verto

如你所见,当链接被调用时,它将会创建一个新的视频元素并赋予其宽度和高度属性,将它添加到3D环境中。

AttachNow函数是real magic发生的地方,我修改了Verto库,当一个session被建立时,调用一个叫attachNow的函数。默认情况下,Verto库使用jQuery形式的标签来初始化,并向标签中添加或移出媒体。我需要一个流来自己管理,这样就可以向以上我展示的空对象中加入video标签。这就可以使A-Frame实现它的逻辑—获取数据并加载到3D环境中a-video标签中一个canvas。

我还向vertoService.js里添加了一个函数:

function updateVideoRes() {
    data.conf.modCommand('vid-res', (unmutedMembers * 1280) + 'x720');
    attachNow();
    document.getElementsByTagName('a-video')[0].setAttribute('width', unmutedMembers*16);
  }
复制代码

UpdateVideoRes被设计成改变FreeSWITCH的Verto会议的输出分辨率。当用户加入会议时,我们想在3D环境下创建一个更长的视频展示。必要的,每次有新成员加入时,我们将输出延长,这样用户就可以在每一端看到其他用户。

视觉

这是最终结果,一个VR环境,包括我和Simon Woodhead。

002

关于WebVR有一点很不错,为了让它全部工作, 你不需要具有VR耳机,你只需要点击按钮,就可以得到全屏的VR体验,就像你带了一个VR耳机一样。你可以查看YouTube上的视频.

我们学到了什么?

这个演示只有一半起到了效果,最大的收获就是即使只有一半演示有效,这也是一个观看视频会议不错的方式。对于VR观看者来说,当他们使用耳机观看时,将他们加入流中不是一个可行的方案。可能这就是为什么微软的HoloLens要是用混合现实优化它的原因。



猜你喜欢

转载自juejin.im/post/5b98c72de51d450e5071cb88