Web
欢迎阅读 Tencent RTC Engine SDK 迁移指南。本文旨在协助开发者将基于 Twilio Video SDK 的实施方案高效迁移到 Tencent RTC Engine SDK。我们将通过详细的技术架构差异分析、迁移准备指引、核心功能迁移示例以及进阶功能对比,帮助您实现快速且无缝的迁移。如果您计划为新项目接入 Tencent RTC Engine SDK,我们建议您从 接入指南 开始学习;如果您想了解 Tencent RTC Engine 的更多信息,我们建议您访问 产品概述。
基本概念与技术架构差异
基本概念对比
本节对 Tencent RTC Engine 和 Twilio Video 服务过程中可能涉及到的一些基本概念进行了对比。要了解更多关于 Tencent RTC Engine 的概念信息,请访问 基本概念。
概念 | Tencent RTC Engine | Twilio Video | 说明 |
房间 | Room | Room | 将 RTC 参与者联系在一起的会话空间。Tencent RTC 使用 roomId(数字),或 strRoomId(字符串),Twilio 使用 name(字符串)。 |
用户 | User | Participant | 参与音视频通话的所有用户。 |
主播 | Anchor | - | 拥有推流权限的用户类型,可向服务端推送和接收音视频流。 |
观众 | Audience | - | 只能接收音视频流的用户类型。 |
应用标识 | SDKAppID | Account SID | 应用唯一标识。 |
鉴权凭证 | UserSig | Access Token | 客户端鉴权凭证。 |
用户标识 | userId | Identity | 用户唯一标识。 |
技术架构差异
Twilio Video 架构
Twilio Video 采用 Track-based(基于轨道) 架构:
开发者需要显式创建
LocalAudioTrack、LocalVideoTrack通过
connect(token, { tracks }) 传入本地轨道来采集并发布本地音视频流通过
room.on('participantConnected')或 TrackPublication.on('subscribed')中的回调来订阅远端音视频流使用
MediaTrack.attach(someHtmlElement)来在网页上渲染视频Tencent RTC Engine 架构
Tencent RTC Engine 采用 API-driven(API 驱动) 架构:
通过
TRTC.create() 生成的单例,直接调用 startLocalVideo() 与 startLocalAudio() 来采集并发布本地音视频流远端流的订阅通过
on(TRTC.EVENT.REMOTE_VIDEO_AVAILABLE) 的回调 + startRemoteVideo() 来完成不需要显式创建和管理轨道对象,但SDK中提供了
getAudioTrack() 与 getVideoTrack() 来获取当前音视频轨道对象以供高级使用这意味着 Tencent RTC Engine 的 API 更加简洁,但同时也保留了对底层轨道对象的访问能力以满足您的高级开发需求。
迁移准备
步骤1. 开通服务
要访问 Tencent RTC Engine 服务,需要创建一个 Tencent RTC Engine 应用程序及其凭据。您可以按照以下步骤在 Tencent RTC 控制台中创建新的 Tencent RTC Engine 应用程序:
1. 注册或登录您的 Tencent RTC 账号,并登录到 Tencent RTC 控制台。
2. 点击 Create Application。
3. 在创建弹窗中,输入您的应用程序名称,选择 RTC Engine,点击 Create。

4. 应用程序创建后,可在 Basic Information 获取以下凭证:
SDKAppID:自动生成的应用 ID,用于唯一标识您的 Tencent RTC 应用程序。
SDKSecretKey:用于生成安全签名 UserSig 的关键参数,用于保障 Tencent RTC 服务的安全访问。

说明:
关于鉴权对比:Twilio Video 使用 Access Token 进行身份验证,而 Tencent RTC 使用 UserSig。两者都是由服务端生成的时效性签名凭证,但生成方式不同。详见 UserSig 鉴权文档。
步骤2. 安装 SDK
Twilio Video SDK (原依赖)
// npmnpm install twilio-video --save
Tencent RTC Engine SDK (新依赖)
// npmnpm install trtc-sdk-v5 --save// yarnyarn add trtc-sdk-v5
步骤3. 导入 SDK
Twilio Video SDK (原依赖)
import * as TwilioVideo from 'twilio-video';
Tencent RTC Engine SDK (新依赖)
import TRTC from 'trtc-sdk-v5'
迁移指引
步骤4. 创建SDK实例
Twilio Video
// Twilio Video 不需要显式创建SDK实例// 直接通过 connect() 静态方法连接房间// 可选:设置日志级别TwilioVideo.Logger.setLevel('debug');
Tencent RTC Engine
const trtc = TRTC.create();
步骤5. 设置事件监听器
Twilio Video
// 当远端用户进入房间...twilioRoom.on('participantConnected', participant => {console.log(`Remote participant ${participant.identity} has connected.`);});// 当远端用户离开房间...twilioRoom.on('participantDisconnected', participant => {console.log(`Remote participant ${participant.identity} has disconnected.`);});
Tencent RTC Engine
// 当远端用户进入房间...trtc.on(TRTC.EVENT.REMOTE_USER_ENTER, event => {console.log(`Remote user ${event.userId} has joined the room.`);});// 当远端用户离开房间...trtc.on(TRTC.EVENT.REMOTE_USER_EXIT, event => {console.log(`Remote user ${event.userId} has left the room.`);});
步骤6. 进入房间/连接到房间
Twilio Video
// 您的Twilio鉴权凭证const accessToken = 'your_twilio_access_token';// 进入房间时设置的参数const connectOptions = {name: 'my_twilio_room'};const twilioRoom = await TwilioVideo.connect(accessToken, connectOptions);
Tencent RTC Engine
进房参数设置
scene 为 TRTC.TYPE.SCENE_RTC 或不提供 scene 参数时会默认创建该类型房间。该模式适合1对1的音视频通话,或者参会人数在 300 人以内的在线会议,支持最大50人开麦。
// 配置进房参数const options = {sdkAppId: 2000000000, // 您应用的SDKAPPIDuserId: 'your_user_id', // 用户IDuserSig: 'your_usersig', // 基于您应用的SDKSECRETKEY与该用户的userId计算出的用户签名strRoomId: 'room_id', // 房间ID (字符串类型)// 默认为实时音视频场景,无需显式声明// scene: TRTC.TYPE.SCENE_RTC};// 如果要使用数字类型的房间ID, 则可以使用roomId; 当strRoomId与roomId都存在时, roomId优先级高于strRoomId:// options.roomId = 123456;try {await trtc.enterRoom(options);console.log('Join rtc room successfully.');} catch (err) {console.error('Fail to join rtc room, err=' + err);}
进房参数设置
scene 为 TRTC.TYPE.SCENE_LIVE 时会创建该类型房间。// 配置进房参数const options = {sdkAppId: 2000000000, // 您应用的SDKAPPIDuserId: 'your_user_id', // 用户IDuserSig: 'your_usersig', // 基于您应用的SDKSECRETKEY与该用户的userId计算出的用户签名strRoomId: 'room_id', // 房间ID (字符串类型)// 互动直播场景scene: TRTC.TYPE.SCENE_LIVErole: TRTC.TYPE.ROLE_ANCHOR // 以主播角色 (默认) 进房,可以发布本地音视频// role: TRTC.TYPE.ROLE_AUDIENCE // 以观众角色进房,没有发布本地音视频的权限,只有收看远端流的权限};// 如果要使用数字类型的房间ID, 则可以使用roomId; 当strRoomId与roomId都存在时, roomId优先级高于strRoomId:// options.roomId = 123456;try {await trtc.enterRoom(options);console.log('Join live room successfully.');} catch (err) {console.error('Fail to join live room, err=' + err);}
步骤7. 采集发布本地音视频流
Twilio Video
// 创建并发布本地视频轨道const localVideoTrack = await twilioVideo.createLocalVideoTrack();twilioRoom.localParticipant.publishTrack(localVideoTrack);// 在网页上渲染视频预览const localVideoContainer = document.getElementById('local-video-container');const localVideoElement = localVideoTrack.attach();localMediaContainer!.appendChild(localVideoElement);// 创建并发布本地音频轨道const localAudioTrack = await twilioVideo.createLocalAudioTrack();twilioRoom.localParticipant.publishTrack(localAudioTrack);// 在网页上添加音频轨道const localAudioElement = localAudioTrack.attach();document.body.appendChild(localAudioElement);
Tencent RTC Engine
// 本地视频流// 获取可用摄像头设备列表const cameraList = await TRTC.getCameraList();// 将第一个可用摄像头的视频流发布到当前房间if(cameraList[0]) {await trtc.startLocalVideo({view: document.getElementById('local-video-container'),options: { cameraId: cameraList[0].deviceId }});}// 取消发布本地视频流await trtc.stopLocalVideo();// 本地音频流// 获取可用麦克风设备列表const microphoneList = await TRTC.getMicrophoneList();// 将第一个可用麦克风的音频流发布到当前房间if(microphoneList[0]) {await trtc.startLocalAudio({options: { microphoneId: microphoneList[0].deviceId }});}// 取消发布本地音频流await trtc.stopLocalAudio();
步骤8. 订阅并播放远端音视频流
Twilio Video
// 当远端用户进入房间...twilioRoom.on('participantConnected', participant => {console.log(`Participant ${participant.sid} has joined the room.`);const remoteContainer = document.createElement('div');remoteContainer.id = `remote-container-${participant.sid}`;// ...并且该远端用户开始推送音视频流时,添加对应的轨道participant.on('trackSubscribed', track => {remoteContainer.appendChild(track.attach());});participant.tracks.forEach(publication => {if (publication.isSubscribed) {remoteContainer.appendChild(publication.track.attach());}});// 该远端用户停止推送音视频流时,移除对应的轨道participant.on('trackUnsubscribed', track => {track.detach().forEach(element => element.remove());});document.body.appendChild(remoteContainer);});twilioRoom.on('participantDisconnected', participant => {console.log(`Participant ${participant.sid} has left the room.`);document.getElementById(`remote-container-${participant.sid}`).remove();});
Tencent RTC Engine
远端用户发布视频时,会触发 TRTC.EVENT.REMOTE_VIDEO_AVAILABLE 事件。您需要在回调内调用 trtc.startRemoteVideo() 来处理并播放对应的远端视频流。当远端用户停止发布视频时,SDK 则会自动停止播放;您也可以调用 trtc.stopRemoteVideo() 来手动停止远端视频流的播放。
// 在调用trtc.enterRoom()进房前设置监听以下事件:// 当远端用户发布视频... (需要监听TRTC.EVENT.REMOTE_VIDEO_AVAILABLE)trtc.on(TRTC.EVENT.REMOTE_VIDEO_AVAILABLE, ({ userId, streamType }) => {const remoteContainerId = `${userId}_${streamType}`const remoteContainer = document.createElement('div');remoteContainer.id = remoteContainerId;document.body.appendChild(remoteContainer);// 在收到该事件时, 调用startRemoteVideo()播放远端视频流trtc.startRemoteVideo({ userId, streamType, view: remoteContainerId });});// 当远端用户停止发布视频时... (需要监听TRTC.EVENT.REMOTE_VIDEO_UNAVAILABLE)trtc.on(TRTC.EVENT.REMOTE_VIDEO_UNAVAILABLE, event => {// 此时 SDK 会自动停止播放,无需手动调用 stopRemoteVideo。});// 手动停止远端用户视频流播放trtc.stopRemoteVideo({ userId: 'some_remote_user' });// 默认情况下,SDK会在远端用户发布音频流时自动播放,因此您无需调用任何API来手动播放。// 如果您需要在远端用户进房时不发布音频,请参考步骤10调用muteRemoteAudio(userId, true)。
步骤9. 静音/取消静音本地音视频
Twilio Video
localVideoTrack.disable(); // 暂停发布本地视频流localVideoTrack.enable(); // 恢复发布本地视频流, 也可以通过enable(true)或enable(false)进行控制localAudioTrack.disable(); // 暂停发布本地音频流localAudioTrack.enable(); // 恢复发布本地音频流, 也可以通过enable(true)或enable(false)进行控制
Tencent RTC Engine
使用 trtc.updateLocalAudio() 与 trtc.updateLocalVideo() 暂时性关闭麦克风与摄像头。该方案不会停止设备采集,而是在“软件层面”暂停采集,因此其优势是重新打开设备时更加快速。
await trtc.updateLocalVideo({ mute: true }); // 暂停发布本地视频流await trtc.updateLocalVideo({ mute: false }); // 恢复发布本地视频流await trtc.updateLocalAudio({ mute: true }); // 暂停发布本地音频流await trtc.updateLocalAudio({ mute: false }); // 恢复发布本地视频流
步骤10. 静音/取消静音远端音视频
Twilio Video
// Twilio Video SDK没有提供直接静音RemoteAudioTrack或RemoteVideoTrack的API// 您可以通过在HTML层面移除对应的渲染节点来实现手动取消订阅的效果// 通过detach()实现const audioElement = remoteAudioTrack.attach();remoteAudioTrack.detach(audioElement);
Tencent RTC Engine
通过 trtc.muteRemoteAudio() 来快速静音或恢复远端音频流播放。对于远端视频流,请使用 trtc.callExperimentalAPI() 下的
pauseRemotePlayer 与 resumeRemotePlayer进行控制。await trtc.muteRemoteAudio('some_user_id', true); // 静音远端音频流await trtc.muteRemoteAudio('some_user_id', false); // 恢复远端音频流await trtc.callExperimentalAPI('pauseRemotePlayer', { userId: 'some_user_id' }); // 暂停远端视频流await trtc.callExperimentalAPI('resumeRemotePlayer', { userId: 'some_user_id' }); // 恢复远端视频流
步骤11. 退出房间
Twilio Video
twilioRoom.disconnect()
Tencent RTC Engine
// 仅退出房间await trtc.exitRoom();// 结束全部业务RTC逻辑,销毁TRTC实例,释放相关资源await trtc.destroy();
进阶功能
屏幕分享
Twilio Video
// Twilio Video SDK没有直接调整提供屏幕分享的API// 需要通过浏览器的navigator.mediaDevices.getDisplayMedia()// 将屏幕分享流转化为LocalVideoTrack再进行播放navigator.mediaDevices.getDisplayMedia().then(stream => {return new TwilioVideo.LocalVideoTrack(stream.getVideoTracks()[0]);});// 更多实现请参考// https://github.com/twilio/video-quickstart-js/blob/master/examples/screenshare/src/helpers.js// https://developer.mozilla.org/zh-CN/docs/Web/API/MediaDevices/getDisplayMedia
Tencent RTC Engine
您可以通过 trtc.startScreenShare() 与 trtc.stopScreenShare() 来更快捷的开启与关闭本地屏幕分享。开启分享后,远端用户会收到
TRTC.EVENT.REMOTE_VIDEO_AVAILABLE 事件,该事件的 streamType 为 TRTC.TYPE.STREAM_TYPE_SUB,您可以通过在回调中调用 trtc.startRemoteVideo() 来拉取屏幕分享流。// 本地: 在调用过trtc.enterRoom()后// 本地开启屏幕分享await trtc.startScreenShare();// 本地停止屏幕分享await trtc.stopScreenShare();
// 远端: 在调用trtc.enterRoom()前注册事件// 远端拉取屏幕分享流trtc.on(TRTC.EVENT.REMOTE_VIDEO_AVAILABLE, ({ userId, streamType }) => {if (streamType === TRTC.TYPE.STREAM_TYPE_MAIN) {// 主流,即该用户的摄像头视频流trtc.startRemoteVideo({ userId, streamType, view: `${userId}_main` });} else {// 辅流 (TRTC.TYPE.STREAM_TYPE_SUB),即该用户的屏幕分享流trtc.startRemoteVideo({ userId, streamType, view: `${userId}_screen` });}})trtc.enterRoom(roomConfig);
音视频编码配置
Twilio Video
// Twilio Video SDK没有直接提供调整音视频编码配置的API// 需要通过浏览器自带的MediaTrackConstraints, 在进房调用connect()时配置视频分辨率与码率, 以及音频采样率等const videoEncodingProfile = {width: 1280,height: 720,frameRate: 24};const audioEncodingProfile = {sampleRate: 16000};await TwilioVideo.connect(token, {video: videoEncodingProfile,audio: audioEncodingProfile});// 更多实现请参考// https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackConstraints
Tencent RTC Engine
在调用 trtc.startLocalAudio() 与 trtc.startLocalVideo() 时,您可以通过添加额外的编码参数
profile 调整用户入房使用的视频编码配置与音频编码配置。// 本地: 在调用过trtc.enterRoom()后// 本地视频上行编码配置// TRTC预定义了一套配置,每个配置对应一组推荐分辨率+帧率+码率的组合const videoEncodingProfile1 = {option: {profile: '1080p' // 分辨率1920*1080, 帧率15fps, 码率2000kbps}}// TRTC同时也支持自定义配置组合const videoEncodingProfile2 = {option: {profile: {width: 1920,height: 1080,frameRate: 15,bitrate: 2200}}}await trtc.startLocalVideo(videoEncodingProfile1);// 支持使用updateLocalVideo进行动态调整await trtc.updateLocalVideo(videoEncodingProfile2);// 本地音频上行配置await trtc.startLocalAudio({ option: { profile: TRTC.TYPE.AUDIO_PROFILE_STANDARD }});
网络质量监控
Twilio Video
// Twilio Video SDK通过connect()时的可选参数networkQuality设置网络质量报告的精细度await TwilioVideo.connect(token, {networkQuality: {local: 1 // Minimal, reporting this participant's network qualityremote: 1 // Minimal, reporting remote paricipants' network quality}});
Tencent RTC Engine
// 本地: 在调用trtc.enterRoom()前注册事件trtc.on(TRTC.EVENT.NETWORK_QUALITY, event => {console.log(`network-quality, uplinkNetworkQuality:${event.uplinkNetworkQuality}, downlinkNetworkQuality: ${event.downlinkNetworkQuality}`)console.log(`uplink RTT:${event.uplinkRTT} loss:${event.uplinkLoss}`)console.log(`downlink RTT:${event.downlinkRTT} loss:${event.downlinkLoss}`)})
自定义采集与渲染
Twilio Video
// Twilio Video的LocalTrack支持直接传入已有的MediaStreamTrack实现自定义采集const customStream = await someCustomCapture(); // e.g. canvas.captureStream(), WebCodecs …const customMSTrack = customStream.getVideoTracks()[0]; // 或 getAudioTracks()[0], 代表自定义采集的MediaStreamTrackconst customTwilioTrack = new TwilioVideo.LocalVideoTrack(customMSTrack, { name: 'my_custom_track' });const room = await TwilioVideo.connect(token, {tracks: [ customTwilioTrack /* 或者直接 customMsTrack */ ],});// 更多实现请参考// https://developer.mozilla.org/en-US/docs/Web/API/MediaStreamTrack
Tencent RTC Engine
在调用 trtc.startLocalAudio() 与 trtc.startLocalVideo() 时,您可以通过添加额外的参数
audioTrack 或 videoTrack 传入自定义采集的 MediaStreamTrack。// 本地: 在调用过trtc.enterRoom()后const customStream = await someCustomCapture(); // e.g. canvas.captureStream(), WebCodecs …const customVideoMSTrack = customStream.getVideoTracks()[0];const customAudioMSTrack = customStream.getAudioTracks()[0];// 自定义采集视频await trtc.startLocalVideo({ option: { videoTrack: customVideoMSTrack }});// 自定义采集音频await trtc.startLocalAudio({ option: { audioTrack: customAudioMSTrack }});
数据通道/自定义消息
Twilio Video
// Twilio Video通过LocalDataTrack对象实现数据通道与自定义消息的收发const dataTrack = new TwilioVideo.LocalDataTrack();const room = await TwilioVideo.connect(token, {name: 'my_room',tracks: [dataTrack /* 以及其他tracks */ ]});// 本地通过dataTrack发送消息dataTrack.send('Hello!');// 远端通过track.kind判断track类型, 并通过track.on('message')回调接受/展示收到的消息participant.on('trackSubscribed', track => {console.log(`Participant "${participant.identity}" added ${track.kind} Track ${track.sid}`);if (track.kind === 'data') {track.on('message', data => {console.log(data);});}});// 更多实现请参考// https://www.twilio.com/docs/video/using-datatrack-api
Tencent RTC Engine
// 本地: 在调用过trtc.enterRoom()后// 本地发送自定义消息trtc.sendCustomMessage({cmdId: 1,data: new TextEncoder().encode('Hello!').buffer // 一次最大发送1KB数据});// 远端通过CUSTOM_MESSAGE事件接收自定义消息trtc.on(TRTC.EVENT.CUSTOM_MESSAGE, event => {// event.userId: 远端发消息的 userId// event.cmdId: 您自定义的消息 Id// event.seq: 消息的序号// event.data: 消息内容,ArrayBuffer 类型console.log(`received custom msg from ${event.userId},message: ${new TextDecoder().decode(event.data)}`);});
// 发送SEI消息// 实例化时需要手动开启SEI收发功能const trtc = TRTC.create({ enableSEI: true });// 本地: 在调用过enterRoom()与startLocalVideo()后, 发送SEI消息try {const unit8Array = new Uint8Array([1, 2, 3]);trtc.sendSEIMessage(unit8Array.buffer);// 消息已通过限制,等待后续视频帧发送。} catch(error) {console.error(error);}// 远端通过SEI_MESSAGE事件接收SEI消息trtc.on(TRTC.EVENT.SEI_MESSAGE, event =>console.log(`received SEI message from ${event.userId},message: ${event.data}`);})
常见问题
Twilio Video 的 Access Token 和 TRTC 的 UserSig 有什么区别?
两者都是用于客户端鉴权的时效性签名凭证,但生成方式不同:
Twilio Access Token:使用 Account SID、API Key SID 和 API Key Secret,通过 Twilio 的 SDK helper libraries 在服务端生成。
TRTC UserSig:使用 SDKAppID 和 SDKSecretKey,通过 HMAC SHA256 算法在服务端生成。
Twilio 的 Room Name(字符串)如何映射到 TRTC 的 Room ID?
TRTC 支持两种房间标识方式:
数字类型 Room ID (
roomId):范围为 1 ~ 4294967294 的整数,推荐使用。字符串类型 Room ID (
strRoomId):长度限制 64 字节,支持字母、数字和部分特殊字符。如果您的 Twilio 项目使用的是字符串形式的房间名称,可以直接使用
strRoomId 进行映射。注意:
同一个 TRTC 应用中,不可混用
roomId 和 strRoomId,两者互不互通。在调用 trtc.enterRoom() 时,如果同时声明了roomId 和 strRoomId,roomId优先级高于strRoomId。TRTC 中远端音频为什么不需要手动订阅?
在 Twilio Video 中,远端音频需要通过
remoteParticipant.on('trackSubscribed') 回调手动处理。而在 TRTC 中,远端音频在用户进入房间后会自动播放,无需任何额外操作。如需控制某个远端用户的音频播放,可以使用 muteRemoteAudio(userId, true/false) 进行静音/取消静音。更多问题