Electron

最近更新时间:2025-03-04 11:42:03

我的收藏
本文将介绍如何在 Electron 环境下,快速接入实时音视频 SDK,实现一个基本的音视频通话。

环境准备

Windows 7+,推荐 Windows 10/11。
MacOS 10.13+。
Node.js 16.20.2 或更高稳定版。

接入指引

步骤1. 导入 SDK

1. 在命令行窗口中执行如下命令,安装 Electron,建议版本号 >= 4.0.0。
npm install electron@24.8.8 --save-dev
注意:
Mac 平台下,Electron 从 25.0.0 版本开始,ElectronSDK 的事件通知会失效,请使用 Electron 25.0.0 以下的版本。
2. 在您的 Electron 项目中使用 npm 命令安装 SDK 包:
npm install trtc-electron-sdk@latest --save
说明:
TRTC Electron SDK 最新版可在 trtc-electron-sdk 中查看。

步骤2. 配置工程

1. 为了正确打包运行 Electron 版本的 TRTC SDK(也就是 trtc_electron_sdk.node 文件),您还需要执行如下命令以安装 native-ext-loader 工具。
npm install native-ext-loader@latest --save-dev
2. 为了解决 webpack 无法处理 Node.js 的内置 'fs' 模块,我们需要执行以下命令安装 path-browserify 工具。
npm install path-browserify --save-dev
3. 以 webpack项目为例,在 webpack.config.js 包含了项目构建的配置信息,webpack.config.js 文件的位置如下:
通常情况下,webpack.config.js 位于项目的根目录。
使用 create-react-app 创建项目的情况下,此配置文件为 node_modules/react-scripts/config/webpack.config.js
使用 vue-cli 创建项目的情况下,webpack 的配置存放在 vue.config.js 配置中的 configureWebpack 属性中。
如您的工程文件经过了定制化,还请自行查找 webpack 配置。
首先使 webpack.config.js 在构建时可以接收名为 --target_platform 的命令行参数,以使代码构建过程按不同的目标平台特点正确打包,在 module.exports 之前添加以下代码:
const os = require('os');
const targetPlatform = (function(){
let target = os.platform();
for (let i=0; i<process.argv.length; i++) {
if (process.argv[i].includes('--target_platform=')) {
target = process.argv[i].replace('--target_platform=', '');
break;
}
}
if (!['win32', 'darwin'].includes) target = os.platform();
return target;
})();
注意:
os.platform() 返回的结果中,"darwin" 表示 Mac 平台。"win32" 表示 Windows 平台,不论 64 位还是 32 位。
然后在 module 选项中添加以下配置,targetPlatform 变量可以使 rewritePath 可以根据不同的目标平台切换不同的配置:
module: {
rules: [
{
test: /\\.node$/,
loader: 'native-ext-loader',
options: {
rewritePath: targetPlatform === 'win32' ? './resources' : '../Resources'
// 针对开发环境
// rewritePath: './node_modules/trtc-electron-sdk/build/Release'
}
},
]
}
该配置的含义是:
打包 Windows 下的 .exe 文件时,让 native-ext-loader[应用程序根目录]/resources 目录下加载 TRTC SDK。
打包 Mac 下的 .dmg 时,让 native-ext-loader[应用程序目录]/Contents/Frameworsk/../Resources 目录下加载 TRTC SDK。
本地开发运行时,让 native-ext-loader./node_modules/trtc-electron-sdk/build/Release 目录下加载 TRTC SDK,请参见 simple demo 配置
接着在 resolve 选项中添加以下配置,该配置用于处理 Node.js 核心模块在浏览器环境中的兼容性问题:
resolve: {
fallback: {
"fs": false,
"path": require.resolve("path-browserify"),
}
}
最后在 externals 中配置下列代码使得 webpack 允许加载本地模块:
externals: {
"trtc-electron-sdk": "commonjs trtc-electron-sdk"
}
4. 设备权限申请示例代码:
const { systemPreferences } = require('electron');

async function checkAndApplyDeviceAccessPrivilege() {
if (process.platform === "darwin" || process.platform === 'win32') {
// 检查并申请摄像头权限
const cameraPrivilege = systemPreferences.getMediaAccessStatus("camera");
if (cameraPrivilege !== "granted") {
await systemPreferences.askForMediaAccess("camera");
}
// 检查并申请麦克风权限
const micPrivilege = systemPreferences.getMediaAccessStatus("microphone");
if (micPrivilege !== "granted") {
await systemPreferences.askForMediaAccess("microphone");
}
// 检查访问屏幕权限
const screenPrivilege = systemPreferences.getMediaAccessStatus("screen");
if (screenPrivilege !== 'granted') {
// 没有屏幕访问权限,做后续处理...
}
}
}

async function createWindow(width = 1366, height = 668) {
await checkAndApplyDeviceAccessPrivilege();
// ... 其他窗口创建逻辑
}

步骤3. 创建 TRTC 实例

创建 TRTC 实例并设置监听,通过设置事件回调接口,您可以监听 SDK 在运行期间所发生的错误信息、警告信息、流量统计信息、网络质量信息以及各种音视频事件。
import TRTCCloud from 'trtc-electron-sdk';
const rtcCloud = TRTCCloud.getTRTCShareInstance();

function onError(errCode, errMsg) {
// errorCode 可参考 https://cloud.tencent.com/document/product/647/32257#.E9.94.99.E8.AF.AF.E7.A0.81.E8.A1.A8
console.log(errCode, errMsg);
}

function onWarning(warningCode, warningMsg) {
// warningCode 可参考 https://cloud.tencent.com/document/product/647/32257#.E8.AD.A6.E5.91.8A.E7.A0.81.E8.A1.A8
console.log(warningCode, warningMsg);
}

rtcCloud.on('onError', onError);
rtcCloud.on('onWarning', onWarning);

步骤4. 进入房间

在调用 enterRoom 接口进房时需要填写两个关键参数,即 TRTCParamsTRTCAppScene ,接下来进行详细介绍:

参数一:TRTCAppScene

该参数用于指定您的应用场景,即在线直播还是实时通话
实时通话:包含 TRTCAppSceneVideoCallTRTCAppSceneAudioCal 两个可选项,分别是视频通话和语音通话,该模式适合 1对1 的音视频通话,或者参会人数在 300 人以内的在线会议。
在线直播:包含 TRTCAppSceneLIVETRTCAppSceneVoiceChatRoom 两个可选项,分别是视频直播和语音直播,该模式适合十万人以内的在线直播场景,但需要您在接下来介绍的 TRTCParams 参数中指定 角色(role) 这个字段,也就是将房间中的用户区分为 主播(anchor) 观众(audience) 两种不同的角色。

参数二:TRTCParams

TRTCParams 由很多的字段构成,但通常您只需要关心如下几个字段的填写:
参数名称
字段含义
补充说明
数据类型
填写示例
SDKAppID
应用 ID
您可以在 实时音视频控制台 中找到这个 SDKAppID,如果没有就单击“创建应用”按钮创建一个新的应用。
数字
1400000123
userId
用户 ID
即用户名,只允许包含大小写英文字母(a-z、A-Z)、数字(0-9)及下划线和连词符。注意 TRTC 不支持同一个 userId 在两台不同的设备上同时进入房间,否则会相互干扰。
字符串
“denny” 或者 “123321”
userSig
进房鉴权票据
您可以使用 SDKAppID 和 userId 计算出 userSig,计算方法请参见 如何计算及使用 UserSig
字符串
eJyrVareCeYrSy1SslI...
roomId
房间号
数字类型的房间号。注意如果您想使用字符串类型的房间号,请使用 strRoomId 字段,而不要使用 roomId 字段,因为 strRoomId 和 roomId 不可以混用。
数字
29834
strRoomId
房间号
字符串类型的房间号。注意 strRoomId 和 roomId 不可以混用,“123” 和 123 在 TRTC 后台服务看来并不是同一个房间。
字符串
“29834”
role
角色
分为“主播”和“观众”两种角色,只有当 TRTCAppScene 被指定为 TRTCAppSceneLIVE 或 TRTCAppSceneVoiceChatRoom 这两种直播场景时才需要指定该字段。
枚举值
TRTCRoleAnchor 或 TRTCRoleAudience
注意:
TRTC 不支持同一个 userId 在两台不同的设备上同时进入房间,否则会相互干扰。
每个端在应用场景 appScene 上必须要进行统一,否则会出现一些不可预料的问题。
在准备好 TRTCAppSceneTRTCParams 这两个参数后,就可以调用 enterRoom 接口函数进入房间了。
import { TRTCParams, TRTCRoleType, TRTCAppScene } from 'trtc-electron-sdk';

const param = new TRTCParams();
param.sdkAppId = 1400000123;
param.userId = "denny";
param.roomId = 123321;
param.userSig = "xxx";
param.role = TRTCRoleType.TRTCRoleAnchor;

// 如果您的场景是“在线直播”,请将应用场景设置为 TRTC_APP_SCENE_LIVE
rtcCloud.enterRoom(param, TRTCAppScene.TRTCAppSceneLIVE);
调用接口后,您会收到来自 TRTCCallback 中的 onEnterRoom(result) 回调:
如果进房成功,result 会是一个正数(result > 0),表示加入房间的时间消耗,单位是毫秒(ms)。
如果进房失败,result 会是一个负数(result < 0),表示进房失败的错误码。
function onEnterRoom(result) {
// onEnterRoom 参见 https://web.sdk.qcloud.com/trtc/electron/doc/zh-cn/trtc_electron_sdk/TRTCCallback.html#event:onEnterRoom
if (result > 0) {
console.log('Enter room succeed');
} else {
// 参见进房错误码 https://cloud.tencent.com/document/product/647/32257#.E8.BF.9B.E6.88.BF.E7.9B.B8.E5.85.B3.E9.94.99.E8.AF.AF.E7.A0.81
console.log('Enter room failed');
}

}

rtcCloud.on('onEnterRoom', onEnterRoom);

步骤5. 打开/关闭摄像头

startLocalPreview(views) 接口启动本地摄像头采集和预览,这个接口会启动默认的摄像头,可以通过 setCurrentCameraDevice() 接口选用其它摄像头 当开始渲染首帧摄像头画面时,您会收到 TRTCCallback 中的 onFirstVideoFrame('') 回调。
Name
Type
Description
views
Array.<HTMLElement> | HTMLElement | null
required
承载预览画面单个的 HTML 块节点或者 HTML 块节点数组
如果传入 null 则不预览摄像头画面,但不影响摄像头采集
// 要预览摄像头图像,您需要在 DOM 中放置一个 HTML 元素,
// 这可以是一个 div 标签,假设其 ID 为 local-video。
const view = document.getElementById('local-video');
rtcCloud.startLocalPreview(view);
stopLocalPreview()接口停止本地摄像头采集和预览。
rtcCloud.stopLocalPreview();

步骤6. 打开/关闭麦克风

startLocalAudio(quality) 开启麦克风采集,请根据您的需求选择以下其中一个声音质量参数quality
const { TRTCAudioQuality } = require('trtc-electron-sdk');
// 开启麦克风采集,设置当前场景为:标准模式(默认模式)
rtcCloud.startLocalAudio(TRTCAudioQuality.TRTCAudioQualityDefault);
// 开启麦克风采集,设置当前场景为:语音模式
// 具有高的噪声抑制能力,有强有弱的网络阻力
rtcCloud.startLocalAudio(TRTCAudioQuality.TRTCAudioQualitySpeech);
// 开启麦克风采集,设置当前场景为:音乐模式
// 为获得高保真度,低音质损失,建议配合专业声卡使用
rtcCloud.startLocalAudio(TRTCAudioQuality.TRTCAudioQualityMusic);
调用 stopLocalAudio() 关闭麦克风采集并停止推送本地音频信息。
rtcCloud.stopLocalAudio()

步骤7. 播放/停止视频流

1. 当您收到 onUserVideoAvailable(userId, 1) 通知时,代表该路画面已经有可用的视频数据帧到达。
2. 您需要调用 startRemoteView(userId, views, streamType) 接口加载该用户的远程画面。 之后您会收到名为 onFirstVideoFrame(userId) 的首帧画面渲染回调。
Parameters:
Name
Type
Description
userId
String
required
对方的用户标识
views
Array.<HTMLElement> | HTMLElement | null
required
承载预览画面单个的 HTML 块节点或者 HTML 块节点数组
如果传入 null 则不预览远端用户画面,但不影响拉取远端视频,适合需要自定义渲染的场景
streamType
TRTCVideoStreamType
required
视频流类型:
TRTCVideoStreamTypeBig 大画面视频流
TRTCVideoStreamTypeSmall 小画面视频流
TRTCVideoStreamTypeSub 辅流(屏幕分享)
// 要预览摄像头图像,您需要在 DOM 中放置一个 HTML 元素,
// 这可以是一个 div 标签,假设其 ID 为 local-video。
const view = document.getElementById('local-video');
rtcCloud.startRemoteView("denny", view, TRTCVideoStreamType.TRTCVideoStreamTypeBig);
注意:
如果主播的上行网络和性能比较好,则可以同时送出大小两路画面。
SDK 不支持单独开启小画面,小画面必须依附于主画面而存在。
调用 stopRemoteView(userId, streamType) 停止播放远端画面。
// 停止播放
rtcCloud.stopRemoteView("denny", TRTCVideoStreamType.TRTCVideoStreamTypeBig); // 只停止播放 denny 画面
rtcCloud.stopAllRemoteView(); // 停止播放所有远端画面
注意:
如果有屏幕分享的画面在显示,则屏幕分享的画面也会一并被关闭。

步骤8. 播放/停止音频流

默认情况下,SDK 将自动播放远程音频,因此您不需要调用任何 API 来手动播放它。
但当您不喜欢自动播放音频时,可以调用 muteRemoteAudio 选择播放或停止远端声音。
// 静音
rtcCloud.muteRemoteAudio("denny", true); // 仅静音 denny
rtcCloud.muteAllRemoteAudio(true); // 静音所有远端用户
// 取消静音
rtcCloud.muteRemoteAudio("denny", false); // 仅取消静音 denny
rtcCloud.muteAllRemoteAudio(false); // 取消静音所有远端用户

步骤9. 退出房间

调用 exitRoom 退出当前的房间,SDK 会通过 TRTCCallback 中的 onExitRoom() 回调通知您。如果您要再次调用 enterRoom() 或者切换到其它的音视频 SDK,请等待 onExitRoom() 回调到来后再执行相关操作, 否则可能会遇到如摄像头、麦克风设备被强占等各种异常问题。
const onExitRoom = (reason) => {
if (reason == 0) {
console.log( "Exit current room by calling the 'exitRoom' api of sdk ...");
} else if (reason == 1) {
console.log("Kicked out of the current room by server through the restful api...");
} else if (reason == 2) {
console.log("Current room is dissolved by server through the restful api...");
}
}

// 监听 `onExitRoom` 回调
rtcCloud.on('onExitRoom', onExitRoom);



步骤10. 应用打包

1. 打包可执行程序

安装打包工具:推荐使用打包工具 electron-builder 进行打包,您可以执行如下命令安装 electron-builder
npm install electron-builder@latest --save-dev

2. 修改 package.json 配置

package.json 位于项目的根目录,其中包含了项目打包所必须的信息。但默认情况下,package.json 中的路径是需要修改才能顺利实现打包的,我们可以按如下步骤修改此文件:
1. 修改 main 配置。
// 多数情况下,main 文件名称可以任意配置,例如 TRTCSimpleDemo 中的可以配置为:
"main": "main.electron.js",

// 但是,使用 create-react-app 脚手架创建的项目,main 文件必须配置为:
"main": "public/electron.js",
2. 复制以下 build 配置,添加到您的 package.json 文件中,这是 electron-builder 需要读取到的配置信息。Mac 下因合规和设备原因,不同 SDK 版本需要使用不同的配置。
10.3 以下版本
10.3 版本
10.3 以上版本
"build": {
"appId": "[appId 请自行定义]",
"directories": {
"output": "./bin"
},
"asar": true,
"win": {
"extraFiles": [
{
"from": "node_modules/trtc-electron-sdk/build/Release/",
"to": "./resources",
"filter": ["**/*"]
}
]
},
"mac": {
"extraFiles": [
{
"from": "node_modules/trtc-electron-sdk/build/Release/trtc_electron_sdk.node",
"to": "./Resources"
}
]
}
}
从 10.3 版本开始,Mac 因合规要求,拆解出了运行时的两个动态库,安装 SDK 后位于 node_modules/trtc-electron-sdk/build/mac-framework/ 目录下,构建应用安装包时,需要在 build.mac.extraFiles 下配置这两个动态库,否则会导致应用包运行时崩溃。
"build": {
"appId": "[appId 请自行定义]",
"directories": {
"output": "./bin"
},
"asar": true,
"win": {
"extraFiles": [
{
"from": "node_modules/trtc-electron-sdk/build/Release/",
"to": "./resources",
"filter": ["**/*"]
}
]
},
"mac": {
"extraFiles": [
{
"from": "node_modules/trtc-electron-sdk/build/Release/trtc_electron_sdk.node",
"to": "./Resources"
},
{
"from": "node_modules/trtc-electron-sdk/build/mac-framework/",
"to": "./Frameworks"
}
]
}
}
从 10.6 版本开始,Mac 下支持原生 ARM64 指令架构的包,同时提供 X64 和 ARM64 指令架构的动态库文件,支持使用 electron-builder 的 “--universal” 参数,构建双指令架构的应用包,优点是可同时在 X64 和 ARM64 芯片的设备上提供优良的性能体验,缺点是应用的包体积大约会增加 70%。不使用 “--universal” 参数时,构建的是单指令架构的应用包,默认与构建时使用的计算机 CPU 芯片类型一致,此时应用安装包在另一种 CPU 芯片类型的机器上将无法安装。
注意:electron-builder 需要升级到 23.0.2 或更高版本。
"build": {
"appId": "[appId 请自行定义]",
"directories": {
"output": "./bin"
},
"asar": true,
"asarUnpack": "**\\\\*.{node,dll}",
"win": {
"extraFiles": [
{
"from": "node_modules/trtc-electron-sdk/build/Release/",
"to": "./resources",
"filter": ["**/*"]
}
]
},
"mac": {
"extraFiles": [
{
"from": "node_modules/trtc-electron-sdk/build/Release/${arch}/trtc_electron_sdk.node",
"to": "./Resources"
},
{
"from": "node_modules/trtc-electron-sdk/build/mac-framework/${arch}/",
"to": "./Frameworks"
}
]
}
}
3. scripts 节点下添加以下构建和打包的命令脚本:
4. 本文以 create-react-appvue-cli 项目为例,其它工具创建的项目也可以参考此配置:
// create-react-app 项目请使用此配置
"scripts": {
"build:mac": "react-scripts build --target_platform=darwin",
"build:win": "react-scripts build --target_platform=win32",
"compile:mac": "electron-builder --mac",
"compile:mac-universal": "electron-builder --mac --universal", // 10.3 及以下版本不支持
"compile:win64": "electron-builder --win --x64",
"pack:mac": "npm run build:mac && npm run compile:mac",
"pack:mac-universal": "npm run build:mac && npm run compile:mac-universal", // 10.3 及以下版本不支持
"pack:win64": "npm run build:win && npm run compile:win64"
}

// vue-cli 项目请使用此配置
"scripts": {
"build:mac": "vue-cli-service build --target_platform=darwin",
"build:win": "vue-cli-service build --target_platform=win32",
"compile:mac": "electron-builder --mac",
"compile:mac-universal": "electron-builder --mac --universal", // 10.3 及以下版本不支持
"compile:win64": "electron-builder --win --x64",
"pack:mac": "npm run build:mac && npm run compile:mac",
"pack:mac-universal": "npm run build:mac && npm run compile:mac-universal", // 10.3 及以下版本不支持
"pack:win64": "npm run build:win && npm run compile:win64"
}
参数
说明
main
Electron 的入口文件,一般情况下可以自由配置。但如果项目使用 create-react-app 脚手架创建,则入口文件必须配置为 public/electron.js
build.asar
是否开启 Electron 应用安装包的压缩功能,默认开启。
build.asarUnpack
添加 build.asar 配置的例外文件。10.3 以后的版本,使用 `electron-builder --mac --universal` 命令构建双指令架构的应用包时,需要此配置,否则可能出现文件合并的失败或报错。
build.win.extraFiles
打包 Windows 程序时,electron-builder 会把 from 所指目录下的所有文件复制到 bin/win-unpacked/resources(全小写)
build.mac.extraFiles
打包 Mac 程序时,electron-builder 会把 from 指向的 trtc_electron_sdk.node 文件复制到 bin/mac/your-app-name.app/Contents/Resources(首字母大写)
build.directories.output
打包文件的输出路径。例如这个配置会输出到 bin 目录下,可根据实际需要修改
build.scripts.build:mac
以 Mac 平台为目标构建脚本
build.scripts.build:win
以 Windows 平台为目标构建脚本
build.scripts.compile:mac
编译为 Mac 下的 .dmg 安装文件
build.scripts.compile:win64
编译为 Windows 下的 .exe 安装文件
build.scripts.pack:mac
先调用 build:mac 构建代码,再调用 compile:mac 打包成 .dmg 安装文件
build.scripts.pack:win64
先调用 build:win 构建代码,再调用 compile:win64 打包成 .exe 安装文件

3. 执行打包命令

打包 Mac.dmg 安装文件
cd [项目目录]
npm run pack:mac
// or
npm run pack:mac-universal
成功执行后,打包工具会生成 bin/your-app-name-0.1.0.dmg 安装文件,请选择此文件发布。
打包 Windows.exe 安装文件
cd [项目目录]
npm run pack:win64
成功执行后,打包工具会生成 bin/your-app-name Setup 0.1.0.exe 安装文件,请选择此文件发布。
注意
TRTC Electron SDK 暂不支持跨平台打包(例如在 Mac 下打包 Windows 的 .exe 文件,或在 Windows 平台下打包 Mac 的 .dmg 文件)。目前我们正在研究跨平台打包方案,敬请期待。

常见问题

您可以在 API 参考 查看所有函数列表及其描述。
如果您的接入和使用中遇到问题,请参见 常见问题

联系我们

如果您是开发者,欢迎您加入我们的 RTC Engine 技术交流平台 zhiliao,进行技术交流和产品沟通。