基於 WebRTC 和 WebVR 實現 VR 視訊通話

聲網Agora發表於2018-09-12
 文章轉載自 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行。

基於 WebRTC 和 WebVR 實現 VR 視訊通話

首先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要是用混合現實優化它的原因。



相關文章