Web平台上的WebRTC并不是其唯一的媒体API。WebVR说明书于几年前被引入来为浏览器中的虚拟现实设备提供支持。目前已经变为新的WebXR设备API说明书。
今年夏天我在ClueCon,Dan Jenkin说使用WebVR,FreeSWITCH向虚拟现实环境中添加一个WebRTC视频会议流是相对简单的。FreeSWITCH是一个流行的开源电话平台,并且已经拥有WebRTC有几年时间了。WebRTC, WebVR,开源-很明显这是很好的webrtcHacks材料。
Dan是一个google开发专家,他喜欢讲将最新的Web API和RTC App结合起来. 以下文章给出了他的代码来说明他是如何使用WebVR将FreeSWITCH Verto WebRTC视频会议转变成虚拟现实会议的。
几周之前,我参加了一个关于WebRTC和WebVR的ClueCON开发者会议。将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。
关于WebVR有一点很不错,为了让它全部工作, 你不需要具有VR耳机,你只需要点击按钮,就可以得到全屏的VR体验,就像你带了一个VR耳机一样。你可以查看YouTube上的视频.
我们学到了什么?
这个演示只有一半起到了效果,最大的收获就是即使只有一半演示有效,这也是一个观看视频会议不错的方式。对于VR观看者来说,当他们使用耳机观看时,将他们加入流中不是一个可行的方案。可能这就是为什么微软的HoloLens要使用混合现实优化它的原因。
所有代码:
代码可以在bitbucket上找到。