基於 Electron 做視訊會議的兩種實現方式

聲網Agora發表於2018-07-18

作者簡介:張乾澤,聲網 Agora Web 研發工程師

對於線上教育、醫療、視訊會議等場景來講,開發面向 Windows、Mac 的跨平臺客戶端是必不可少的一步。在過去,每個作業系統的應用需用特定的程式語言編寫,每個客戶端都需要單獨開發。而現在我們可以利用多種工具、框架進行跨平臺開發。Electron 就是其中最熱門的一個。

Electron 的前身是Atom Shell,是基於Node.js 和 Chromium 開源專案。它讓前端開發者也可以使用 JavaScript,HTML 和 CSS 構建跨平臺的桌面應用程式。

Electron 相容 Mac、Windows 和 Linux。利用它構建的應用可在這三個作業系統上面執行。我們在很多著名專案中都能看到它的身影,比如 Slack、Cocos Creator、Visual Studio Code 等 500 多個專案。

本文將為大家分析利用 Electron 做視訊會議應用的幾種實現思路及其優缺點,同時結合 demo 例項,分享如何基於 Electron 與聲網 Agora Web SDK 開發一個視訊會議應用。

實現視訊會議的幾種思路

如何利用 Electron 實現一個視訊會議應用?這主要取決於使用什麼技術來實現作為業務核心的 RTC 部分。

基於 Electron 做視訊會議的兩種實現方式

第一種思路是使用 C++ SDK 來實現。我們可以通過 NodeJS 外掛 node-gyp 將 C++ 的庫編譯成 NodeJS 可以直接使用的檔案,介面部分則通過 Web 來實現,最後 RTC 業務部分則使用編譯的外掛直接呼叫 C++ 介面。

這種方式的優點是直接呼叫 C++ 介面,在效能和穩定性上有一定優勢。但是,缺點是 Native 模組與 Web 模組的互動會相對複雜。

儘管 NodeJS 可以直接呼叫 C++ 的介面,但若 C++ 要通過回撥向 Node 部分傳遞資料,則需要確保資料傳輸到 Electron 所在的執行緒上, Electron 才可以收到回撥。又比如,若 C++ SDK 使用了具有平臺差異的動態庫依賴,則在使用 node-gyp 編譯的過程中必須在不同平臺上編譯不同的版本才可以在 Electron 中正常使用。

基於 Electron 做視訊會議的兩種實現方式

第二種思路是使用 WebRTC,即介面部分和 RTC 業務部分都通過 Web 來實現。

這種方法的優點是整合和除錯十分簡單,大部分工作可以在瀏覽器中完成後直接近乎無縫移植到 Electron。

不過,由於 WebRTC 缺少服務端設計和部署方案,我們首先還需要將 WebRTC 與 Janus 等開源專案結合,解決伺服器的部署、NAT 穿透等問題,實現 RTC 部分,這也是這種實現方法的難點。但如果通過 Agora Web SDK 來實現 RTC 部分,則不需要擔心以上問題,也是目前最快速簡便的實現方法。

通過與 WebRTC 技術結合,Agora Web SDK 實現了網頁端多方音視訊通訊,可以快速實現 RTC 部分的開發。WebRTC 使用者的音視訊資料經由 Agora.io 的 SD-RTN 實時雲傳輸,可以最大程度上保證公網的傳輸質量,結合 WebRTC 自有的丟包/丟幀重傳,以及頻寬預測,動態位元速率調整等策略,可以達到非常良好的多方通話使用者體驗。

針對這方面的整合,我們也已經在 Github 上提供了一個開源的 demo 專案。我們下面來簡要梳理一下 demo 中如何實現核心音視訊通話功能。

基於 Agora Web SDK 實現音視訊通話

我們需要在 Electron 環境中建立一個名為 web-app 的目錄,在裡面建立基本的 Web 部分內容並快速實現一個視訊通話通能。

建立 AgoraRTC 例項並加入頻道:

let client = AgoraRTC.CreateClient({mode:"interop"}) 
複製程式碼

初始化 appid 並加入頻道:

 client.init(options.key, () => {

                console.log("AgoraRTC client initialized")

                client.join(options.key, options.channel, options.uid, (uid) => {

                    console.log("User " + uid + " join channel successfully")

                    console.log(new Date().toLocaleTimeString())

                    // create localstream

                    resolve(uid)

                })

            })

複製程式碼

建立本地流並推送:

let stream = AgoraRTC.creatStream(merge(defaultConfig.config))
localStream.init(() =>{
           client.publish(localStream, err => {
                  console.log("Publish local stream error: " + err);
                  localStream.play("element_id")
           })
},
複製程式碼

在完成上面的步驟後,你應該就能看到自己的視訊畫面了,下一步我們要讓這部分程式碼在 Electron 的 App 容器中跑起來。

建立 BrowserWindow 例項並讀取 web-app 目錄中的內容:

const electron = require('electron')
// Module to control application life.
const app = electron.app
// Module to create native browser window.
const BrowserWindow = electron.BrowserWindow

let mainwindow

function createWindow () {

  // Create the browser window.

mainWindow = new BrowserWindow({width: 800, height: 600})
 // and load the index.html of the app.
  mainWindow.loadURL(url.format({
    pathname: path.join(__dirname, './web-app/dist/index.html'),
    protocol: 'file:',
    slashes: true
  }))
mainWindow.webContents.openDevTools()

//Open the DevTools
//mainWindow.webContents.openDevTools()

//Emitted when the window is closed.
mainWindow.on('closed',function(){
  // Dereference the window object, usually you would store windows

  // in an array if your app supports multi windows, this is the time

  // when you should delete the corresponding element.
   mainWindow = null

})
複製程式碼

完成後使用 npm start 啟動 Electron 即可。

最後 點選這裡 檢視 demo 原始碼,同時可通過網站瞭解SDK介面。


想聽到更多關於線上教育、多人視訊會議的開發乾貨?9月7日 - 8日全球最大規模的實時網際網路技術大會「RTC 2018 實時網際網路大會」上,將有來自 Google、華為、Twitch、滬江 CCTalk等知名團隊的技術大咖與你分享。門票限免中,點選這裡即可免費報名

相關文章