做者简介:张乾泽,声网 Agora Web 研发工程师
对于在线教育、医疗、视频会议等场景来说,开发面向 Windows、Mac 的跨平台客户端是必不可少的一步。在过去,每一个操做系统的应用需用特定的编程语言编写,每一个客户端都须要单独开发。而如今咱们能够利用多种工具、框架进行跨平台开发。Electron 就是其中最热门的一个。html
Electron 的前身是Atom Shell,是基于Node.js 和 Chromium 开源项目。它让前端开发者也可使用 JavaScript,HTML 和 CSS 构建跨平台的桌面应用程序。前端
Electron 兼容 Mac、Windows 和 Linux。利用它构建的应用可在这三个操做系统上面运行。咱们在不少著名项目中都能看到它的身影,好比 Slack、Cocos Creator、Visual Studio Code 等 500 多个项目。node
本文将为你们分析利用 Electron 作视频会议应用的几种实现思路及其优缺点,同时结合 demo 实例,分享如何基于 Electron 与声网 Agora Web SDK 开发一个视频会议应用。git
如何利用 Electron 实现一个视频会议应用?这主要取决于使用什么技术来实现做为业务核心的 RTC 部分。github
第一种思路是使用 C++ SDK 来实现。咱们能够经过 NodeJS 插件 node-gyp 将 C++ 的库编译成 NodeJS 能够直接使用的文件,界面部分则经过 Web 来实现,最后 RTC 业务部分则使用编译的插件直接调用 C++ 接口。web
这种方式的优势是直接调用 C++ 接口,在性能和稳定性上有必定优点。可是,缺点是 Native 模块与 Web 模块的交互会相对复杂。npm
尽管 NodeJS 能够直接调用 C++ 的接口,但若 C++ 要经过回调向 Node 部分传递数据,则须要确保数据传输到 Electron 所在的线程上, Electron 才能够收到回调。又好比,若 C++ SDK 使用了具备平台差别的动态库依赖,则在使用 node-gyp 编译的过程当中必须在不一样平台上编译不一样的版本才能够在 Electron 中正常使用。编程
第二种思路是使用 WebRTC,即界面部分和 RTC 业务部分都经过 Web 来实现。windows
这种方法的优势是集成和调试十分简单,大部分工做能够在浏览器中完成后直接近乎无缝移植到 Electron。浏览器
不过,因为 WebRTC 缺乏服务端设计和部署方案,咱们首先还须要将 WebRTC 与 Janus 等开源项目结合,解决服务器的部署、NAT 穿透等问题,实现 RTC 部分,这也是这种实现方法的难点。但若是经过 Agora Web SDK 来实现 RTC 部分,则不须要担忧以上问题,也是目前最快速简便的实现方法。
经过与 WebRTC 技术结合,Agora Web SDK 实现了网页端多方音视频通信,能够快速实现 RTC 部分的开发。WebRTC 用户的音视频数据经由 Agora.io 的 SD-RTN 实时云传输,能够最大程度上保证公网的传输质量,结合 WebRTC 自有的丢包/丢帧重传,以及带宽预测,动态码率调整等策略,能够达到很是良好的多方通话用户体验。
针对这方面的集成,咱们也已经在 Github 上提供了一个开源的 demo 项目。咱们下面来简要梳理一下 demo 中如何实现核心音视频通话功能。
咱们须要在 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 便可。