You need to enable JavaScript to run this app.
导航

Electron

最近更新时间2023.10.31 19:49:03

首次发布时间2022.06.23 19:44:25

通过本文的指引,你可以在集成 RTC SDK 后,快速构建基础应用,实现基本实时音视频通话。

前提条件

  • 有效的 App Id 和临时 Token

  • PC:Windows 或 MacOS 操作系统,可访问互联网。

    自 RTC SDK V3.50 版本,支持使用搭载 arm64 架构芯片的 Mac 进行开发。

  • Electron 开发环境

操作步骤

1. 创建项目

创建项目文件夹,并创建以下文件:

  • package.json: 用于安装和管理项目依赖项。

  • index.html:用于设计 app 的用户界面。

  • main.js:主进程文件。

  • renderer.js:渲染进程文件。

2. 集成 SDK

【推荐】NPM 方式

在项目的根目录运行以下命令:

npm install @volcengine/vertc-electron-sdk --save

如果当前项目路径尚未配置 package.json,运行上述安装命令前,先运行 npm init 进行初始化配置。

离线方式

  1. 下载 Electron SDK

  2. 将下载下来的 SDK 复制到你项目的目录中。比如:node_modules/vertc-electron-sdk

3. 实现视频通话

安装完成后,通过如下代码将 SDK 引入至你的项目中。比如:vertc-electron-sdk

const SDK = require('vertc-electron-sdk');
// 这里示例从 node_modules 文件引入
// 你也可以将 SDK 放置到适合你的目录

创建用户界面

将以下代码复制到 index.html,创建一个包含远端视频窗口和本地视频窗口的界面

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Electron Quickstart</title>
</head>
<body>
  <h1>Electron Quickstart</h1>
  <!--本地视频窗口 -->
  <div id="join-channel-local-video" style="width: 240px; height: 180px; background-color: lightblue;"></div>
  <!--远端视频窗口 -->
  <div id="join-channel-remote-video" style="width: 240px; height: 180px; background-color: lightblue;"></div>
</body>
</html>

主进程

以下代码复制到 main.js 文件,实现基本的 Electron 项目主进程

const { app, BrowserWindow } = require('electron')
const path = require('path')

// 如果你使用 Electron 9.x 及以上版本,将 allowRendererProcessReuse 设为 false。
app.allowRendererProcessReuse = false

function createWindow() {
  // 创建浏览器窗口
  const mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      preload: path.join(__dirname, 'renderer.js'),
      nodeIntegration: true
    }
  })

  // 加载 index.html 文件的内容
  mainWindow.loadFile('./index.html')
  // 开启开发者工具
  mainWindow.webContents.openDevTools()
}

// 管理 Electron 应用的浏览器窗口
app.whenReady().then(() => {
  createWindow()
  // 如果当前没有窗口打开,则新建一个窗口(适用于 macOS)
  app.on('activate', function () {
    if (BrowserWindow.getAllWindows().length === 0) {
      createWindow()
    }
  })
})

// 如果所有窗口都已关闭,则退出 Electron 应用(适用于 Windows)
app.on('window-all-closed', function () {
  if (process.platform !== 'darwin') app.quit()
})

申请麦克风和摄像头权限

Mac OS 10.14 以后版本,需要申请麦克风、摄像头权限。在主进程中,调用 Electron 的 systemPreferences.askForMediaAccess() 接口,申请摄像头、麦克风权限。参考代码如下。

async function checkAndApplyDeviceAccessPrivilege() {
  // 检查并申请摄像头权限
  const cameraPrivilege = systemPreferences.getMediaAccessStatus('camera');
  console.log(`checkAndApplyDeviceAccessPrivilege before apply cameraPrivilege: ${cameraPrivilege}`);
  if (cameraPrivilege !== 'granted') {
    await systemPreferences.askForMediaAccess('camera');
  }
  // 检查并申请麦克风权限
  const micPrivilege = systemPreferences.getMediaAccessStatus('microphone');
  console.log(`checkAndApplyDeviceAccessPrivilege before apply micPrivilege: ${micPrivilege}`);
  if (micPrivilege !== 'granted') {
    await systemPreferences.askForMediaAccess('microphone');
  }

渲染进程

实现视频通话需要进行以下步骤

  1. 创建 RTCVideo 实例

  2. 调用 createRTCVideo 初始化 RTCVideo,需要传入 appid,本地日志路径,例如:logPath = window.veTools.getLogPath();

  3. 使用 startVideoCapture 开启视频采集,在通话中使用视频功能

  4. 使用 startAudioCapture 开启音频采集,在通话中使用音频功能

  5. 使用 setupLocalVideo 设置本地视图,渲染本地图像

  6. 使用 setupRemoteVideo 设置远端视图,在本地渲染远端图像

  7. 在 RTCVideo 实例中调用 createRTCRoom 创建 RTCRoom,需要传入 roomId

  8. 在 RTCRoom 实例中调用 joinRoom 加入房间,需要传入 token,roomId ,userId,用户信息和房间参数配置。默认自动发布、订阅音视频流。

rtcRoom.joinRoom(token: string,{ uid: string }, roomConfig: RTCRoomConfig): number;
  1. 离开房间,并释放 RTCRoom 和 RTCVideo。
// 离开房间
rtcRoom.leaveRoom(): any;
// 销毁RTCRoom
rtcRoom.destroy(): any;
//销毁RTCVideo
rtcVideo.destroyRTCVideo()

基础音视频通话 API 时序图:

alt

将如下代码复制到 renderer.js 文件,

window.addEventListener('DOMContentLoaded',() => {
    const SDK = require('vertc-electron-sdk')
    const RTCVideo = SDK.RTCVideo;
   
    const os = require('os')
    const path = require('path')
    
    // 填入你的 App ID
    const APPID = ""
    // 填入你的 Token
    const token = ""
    
    const localVideoContainer = document.getElementById('join-channel-local-video')
    const remoteVideoContainer = document.getElementById('join-channel-remote-video')
    const sdkLogPath = path.resolve(os.homedir(), "./test.log")
    
    let rtcVideo = new RTCVideo()
    let rtcRoom ;
    rtcVideo.createRTCVideo(APPID,sdkLogPath,JSON.stringify('') )
    
    rtcVideo.on('onFirstRemoteVideoFrameDecoded', (key, info) => {        rtcVideo.setupRemoteVideo(key.user_id,key.room_id, remoteVideoContainer, 1);
    });    
    // 开启视频模块
    rtcVideo.startVideoCapture();
    rtcVideo.startAudioCapture();
        // 加入频道
    let roomConfig = {        room_profile_type: 1,
        is_auto_publish: true,
        is_auto_subscribe_audio: true,
        is_auto_subscribe_video: true
    };
    rtcRoom = rtcVideo.createRTCRoom(roomId);
    let ret = rtcRoom.joinRoom(token,{ uid: userId }, roomConfig);
    rtcVideo.setupLocalVideo(localVideoContainer,roomId)
    console.log('join room ret : ' + ret)    
})

4. 打包可执行程序

推荐使用 electron-builder 和 native-ext-loader 工具打包你的 Electron 项目。

安装打包工具

工具安装命令如下:

  • electron-builder
npm install electron-builder@latest --save-dev
  • native-ext-loader
npm install native-ext-loader@latest --save-dev

配置构建文件

  1. 找到 webpack.config.js。通常你可以在项目根目录找到 webpack.config.js。

    • RTC 快速开始 demo 项目中,构建配置文件为 webpack.config.preload.js。
    • 对于一个 vue 项目,你可以在 vue.config.js 配置中的 chainWebpack 选项中进行相应配置。
    • 对于一个 react 项目,如果是通过 create-react-app 构建的项目,配置文件路径为 node_modules/react-scripts/config/webpack.config.js
  2. 参考 RTC 快速 Demo 项目的 webpack.config.preload.js 为你的项目进行构建配置。native-ext-loader 将在打包后的 app/@volcengine/vertc-electron-sdk/build/Release 子目录中加载对应 .node 模块。

rules: [
      {
        test: /\.node$/,
        loader: "native-ext-loader",
        options: {
          emit: false,
          basePath: ["@volcengine/vertc-electron-sdk/build/Release"], // 这里写入火山electron node 模块本地路径
        },
      },
    ]

参考 RTC 快速 Demo 项目的 package.json 和 copySdkAddon.js 脚本为你的项目进行配置。

  1. 在 package.json 指定打包配置,位于项目根目录。
"main": "index.js",// 指定实际项目入口文件
"asar": true,// 用于将 web 资源文件压缩并加密
"asarUnpack": "@volcengine/vertc-electron-sdk" // 如果 asar 为true,需要指定 node 模块所在的路径,用来排除需要压缩的 node 模块,否则 node 无法正常加载
  1. scripts 节点下调整打包命令,在打包时调用 copySdkAddon 脚本,将 node_modules 里 RTC 的 node 复制到 app 目录。

你可以在 Electron 快速开始 Demo 中找到 copySdkAddon 脚本。

"scripts": {
    "start": "electron ./app",
    "build": "yarn buildApp && yarn start",
    "buildApp": "yarn copySdkAddon && yarn buildMain && yarn buildRenderer && yarn buildSetting && yarn buildPreload ",
    "buildMain": "webpack --config webpack.config.main.js --mode development",
    "buildRenderer": "webpack --config webpack.config.renderer.js --mode development",
    "buildPreload": "webpack --config webpack.config.preload.js --mode development",
    "buildSetting": "webpack --config webpack.config.setting.js --mode development",
    "copySdkAddon": "node ./scripts/copySdkAddon.js",
    "packageWin32": "electron-builder --win --ia32 --config builder-config-win.js",
    "packageWin64": "electron-builder --win --x64 --config builder-config-win64.js",
    "packageDarwin": "electron-builder --mac --x64 --config builder-config-mac.js",
    "packageArm64": "electron-builder build --arm64 --config builder-config-arm64.js"
  },
  1. 运行打包命令,例如:
npm run packageWin32

成功执行后,打包工具会生成可执行文件。

常见问题

Q:使用 electron-builder 工具打包时,node 模块加载报错:RTCVideo is not a constructor。
A:说明 RTC 的 .node 模块没有被正确的打包到可执行程序中。建议按照打包可执行程序中的步骤重新打包项目。

更多问题和解决办法参见 Electron 集成 RTC SDK 常见问题