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上找到。