• 서비스
  • 가격
  • 리소스
  • 기술지원
이 페이지는 현재 영어로만 제공되며 한국어 버전은 곧 제공될 예정입니다. 기다려 주셔서 감사드립니다.

Web

This document helps you move a Web app from the Twilio Video SDK to the Tencent RTC Engine SDK. It covers key architecture differences, step-by-step migration instructions, practical feature examples, and advanced feature comparisons to help you migrate smoothly.
If you’re starting a new project with Tencent RTC Engine, begin with the Integration Guide. For a high-level introduction, see the Product Overview.

Core concepts and architecture differences

Concept Comparison

This section maps key concepts between Tencent RTC Engine and Twilio Video. For Tencent RTC terminology, see Basic Concepts.
Concept
Tencent RTC Engine
Twilio Video
Description
Room
Room
Room
The session space that connects RTC participants. Tencent RTC uses roomId (number) or strRoomId (string); Twilio uses name (string).
User
User
Participant
All users participating in audio/video calls.
Anchor
Anchor
-
User type with permission to publish streams; can send and receive audio/video streams.
Audience
Audience
-
User type that can only receive audio/video streams.
Application Identifier
SDKAppID
Account SID
Unique identifier for the application.
Authentication Credential
UserSig
Access Token
Credential used for client authentication.
User Identifier
userId
Identity
Unique identifier for each user.

Technical Architecture Differences

Twilio Video Architecture

Twilio Video uses a track-based architecture:
You explicitly create LocalAudioTrack and LocalVideoTrack.
You call connect(token, { tracks }) and pass the local tracks to publish audio/video.
You subscribe to remote tracks via events such as room.on('participantConnected') or TrackPublication.on('subscribed').
You render media in the DOM using MediaTrack.attach(someHtmlElement).

Tencent RTC Engine Architecture

Tencent RTC Engine uses an API-driven architecture:
You create a client with TRTC.create() and call APIs such as startLocalVideo() / startLocalAudio() to capture and publish.
You listen for remote availability events (for example, TRTC.EVENT.REMOTE_VIDEO_AVAILABLE) and then call startRemoteVideo().
You generally don’t manage track objects yourself. For advanced scenarios, you can still access underlying tracks via getAudioTrack() and getVideoTrack().
This API design is more streamlined, while still providing access to underlying tracks for advanced scenarios.

Migration Preparation

Step 1. Activate the Service

To use Tencent RTC Engine services, create an application and obtain credentials by following these steps:
1. Register or log in to your Tencent RTC account, then access the Tencent RTC Console.
2. Click Create Application.
3. In the popup, enter your application name, select RTC Engine, and click Create.



4. After the application is created, retrieve these credentials from Basic Information:
SDKAppID: Automatically generated; uniquely identifies your Tencent RTC application.
SDKSecretKey: Used to generate secure UserSig credentials for accessing Tencent RTC services.


Note:
Authentication Comparison: Twilio Video uses Access Token for authentication, whereas Tencent RTC uses UserSig. Both are time-limited credentials generated on the server side, but the generation methods differ. See UserSig Authentication Documentation.

Step 2. Install SDK

Twilio Video SDK (Original Dependency)

// npm
npm install twilio-video --save

Tencent RTC Engine SDK (New Dependency)

Install trtc-sdk-v5 using npm or yarn:
// npm
npm install trtc-sdk-v5 --save

// yarn
yarn add trtc-sdk-v5
Alternatively, download trtc-sdk-v5, extract it, and copy the trtc-sdk-v5 directory to your project's node_modules.

Step 3. Import SDK

Twilio Video SDK (Original Dependency)

import * as TwilioVideo from 'twilio-video';

Tencent RTC Engine SDK (New Dependency)

import TRTC from 'trtc-sdk-v5'
Note:
If you need to manually import the JS file, you can download trtc.js and include it with a `<script>` tag:
<script src="/your_path/trtc.js"></script>

Migration Guide

Step 4. Create SDK Instance

Twilio Video

// Twilio Video does not require explicit SDK instance creation
// Connect to the room directly via the connect() static method
// Optional: Set log level
TwilioVideo.Logger.setLevel('debug');

Tencent RTC Engine

Create a TRTC instance using TRTC.create():
const trtc = TRTC.create();

Step 5. Set Event Listeners

Twilio Video

// When a remote user joins the room...
twilioRoom.on('participantConnected', participant => {
console.log(`Remote participant ${participant.identity} has connected.`);
});

// When a remote user leaves the room...
twilioRoom.on('participantDisconnected', participant => {
console.log(`Remote participant ${participant.identity} has disconnected.`);
});

Tencent RTC Engine

Use trtc.on() to register event listeners for TRTC Events:
// When a remote user joins the room...
trtc.on(TRTC.EVENT.REMOTE_USER_ENTER, event => {
console.log(`Remote user ${event.userId} has joined the room.`);
});

// When a remote user leaves the room...
trtc.on(TRTC.EVENT.REMOTE_USER_EXIT, event => {
console.log(`Remote user ${event.userId} has left the room.`);
});

Step 6. Join/Connect to Room

Twilio Video

// Your Twilio access token
const accessToken = 'your_twilio_access_token';

// Options for joining the room
const connectOptions = {
name: 'my_twilio_room'
};

const twilioRoom = await TwilioVideo.connect(accessToken, connectOptions);

Tencent RTC Engine

Use trtc.enterRoom() to create and join a room. Choose from the following scenarios:
RTC Room Scenario (Default)
Interactive Live Streaming Scenario
When the scene parameter is set to TRTC.TYPE.SCENE_RTC or omitted, a real-time audio/video room is created (default). This mode supports up to 300 participants, with up to 50 users able to publish streams.
// Set room entry parameters
const options = {
sdkAppId: 2000000000, // Your SDKAppID
userId: 'your_user_id', // User ID
userSig: 'your_usersig', // UserSig generated with SDKSecretKey and userId
strRoomId: 'room_id', // Room ID (string)
// scene: TRTC.TYPE.SCENE_RTC // Optional, defaults to real-time audio/video
};
// To use a numeric room ID, set options.roomId = 123456; roomId takes precedence if both are set.

try {
await trtc.enterRoom(options);
console.log('Joined RTC room successfully.');
} catch (err) {
console.error('Failed to join RTC room, err=' + err);
}
If the scene parameter is set to TRTC.TYPE.SCENE_LIVE, an interactive live streaming room is created. This mode supports up to 100,000 participants. Specify the role field to define the user's role when joining. Use trtc.switchRole() to change roles in the room.
// Set room entry parameters
const options = {
sdkAppId: 2000000000, // Your SDKAppID
userId: 'your_user_id', // User ID
userSig: 'your_usersig', // UserSig generated with SDKSecretKey and userId
strRoomId: 'room_id', // Room ID (string)
scene: TRTC.TYPE.SCENE_LIVE, // Interactive live streaming scenario
role: TRTC.TYPE.ROLE_ANCHOR // Join as anchor (default), can publish streams
// role: TRTC.TYPE.ROLE_AUDIENCE // Join as audience, can only watch remote streams
};
// To use a numeric room ID, set options.roomId = 123456; roomId takes precedence if both are set.

try {
await trtc.enterRoom(options);
console.log('Joined live room successfully.');
} catch (err) {
console.error('Failed to join live room, err=' + err);
}

Step 7. Capture and Publish Local Audio/Video Streams

Twilio Video

// Create and publish local video track
const localVideoTrack = await twilioVideo.createLocalVideoTrack();
twilioRoom.localParticipant.publishTrack(localVideoTrack);

// Render video preview in the browser
const localVideoContainer = document.getElementById('local-video-container');
const localVideoElement = localVideoTrack.attach();
localMediaContainer!.appendChild(localVideoElement);

// Create and publish local audio track
const localAudioTrack = await twilioVideo.createLocalAudioTrack();
twilioRoom.localParticipant.publishTrack(localAudioTrack);

// Add audio track to the web page
const localAudioElement = localAudioTrack.attach();
document.body.appendChild(localAudioElement);

Tencent RTC Engine

Use trtc.startLocalAudio() and trtc.startLocalVideo() to capture and publish streams from local camera and microphone devices.
Retrieve available devices with TRTC.getCameraList() and TRTC.getMicrophoneList():
// Local video stream
// Get available camera devices
const cameraList = await TRTC.getCameraList();

// Publish video from the first available camera
if (cameraList[0]) {
await trtc.startLocalVideo({
view: document.getElementById('local-video-container'),
options: { cameraId: cameraList[0].deviceId }
});
}

// Stop publishing local video stream
await trtc.stopLocalVideo();

// Local audio stream
// Get available microphone devices
const microphoneList = await TRTC.getMicrophoneList();

// Publish audio from the first available microphone
if (microphoneList[0]) {
await trtc.startLocalAudio({
options: { microphoneId: microphoneList[0].deviceId }
});
}

// Stop publishing local audio stream
await trtc.stopLocalAudio();

Step 8. Subscribe and Play Remote Audio/Video Streams

Twilio Video

// When a remote user joins the room...
twilioRoom.on('participantConnected', participant => {
console.log(`Participant ${participant.sid} has joined the room.`);
const remoteContainer = document.createElement('div');
remoteContainer.id = `remote-container-${participant.sid}`;
// When remote user starts publishing streams, add tracks
participant.on('trackSubscribed', track => {
remoteContainer.appendChild(track.attach());
});
participant.tracks.forEach(publication => {
if (publication.isSubscribed) {
remoteContainer.appendChild(publication.track.attach());
}
});
// When remote user stops publishing streams, remove tracks
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

When a remote user publishes video, the TRTC.EVENT.REMOTE_VIDEO_AVAILABLE event fires. Call trtc.startRemoteVideo() to play the remote video stream. When the remote user stops publishing, the SDK automatically stops playback; you can also call trtc.stopRemoteVideo() manually.
// Set up event listeners before calling trtc.enterRoom():

// When a remote user publishes video...
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);

// Play the remote video stream
trtc.startRemoteVideo({ userId, streamType, view: remoteContainerId });
});

// When a remote user stops publishing video...
trtc.on(TRTC.EVENT.REMOTE_VIDEO_UNAVAILABLE, event => {
// The SDK automatically stops playback; no manual action required.
});

// Manually stop playback of a remote user's video stream
trtc.stopRemoteVideo({ userId: 'some_remote_user' });

// By default, remote audio streams are automatically played. To block playback, see Step 10 and call muteRemoteAudio(userId, true).

Step 9. Mute/Unmute Local Audio/Video

Twilio Video

localVideoTrack.disable(); // Pause publishing local video stream
localVideoTrack.enable(); // Resume publishing local video stream

localAudioTrack.disable(); // Pause publishing local audio stream
localAudioTrack.enable(); // Resume publishing local audio stream

Tencent RTC Engine

Use trtc.updateLocalAudio() and trtc.updateLocalVideo() to temporarily mute or unmute the microphone and camera. This does not stop device capture, but pauses it at the software layer for faster resume.
await trtc.updateLocalVideo({ mute: true }); // Pause publishing local video stream
await trtc.updateLocalVideo({ mute: false }); // Resume publishing local video stream

await trtc.updateLocalAudio({ mute: true }); // Pause publishing local audio stream
await trtc.updateLocalAudio({ mute: false }); // Resume publishing local audio stream

Step 10. Mute/Unmute Remote Audio/Video

Twilio Video

// Twilio Video SDK does not provide a direct API to mute RemoteAudioTrack or RemoteVideoTrack
// You can manually remove the corresponding render node at the HTML level to achieve the same effect

// Using detach()
const audioElement = remoteAudioTrack.attach();
remoteAudioTrack.detach(audioElement);

Tencent RTC Engine

To mute or resume remote audio streams, use trtc.muteRemoteAudio(). For remote video, control playback with trtc.callExperimentalAPI() using pauseRemotePlayer and resumeRemotePlayer.
await trtc.muteRemoteAudio('some_user_id', true); // Mute remote audio stream
await trtc.muteRemoteAudio('some_user_id', false); // Resume remote audio stream

await trtc.callExperimentalAPI('pauseRemotePlayer', { userId: 'some_user_id' }); // Pause remote video stream
await trtc.callExperimentalAPI('resumeRemotePlayer', { userId: 'some_user_id' }); // Resume remote video stream

Step 11. Leave Room

Twilio Video

twilioRoom.disconnect()

Tencent RTC Engine

Call trtc.exitRoom() to leave the current room. Use trtc.switchRoom() to switch rooms.
After leaving, if you no longer need the TRTC instance, call trtc.destroy() to release resources.
// Leave the room only
await trtc.exitRoom();

// End all RTC operations, destroy the TRTC instance, and release resources
await trtc.destroy();

Advanced Features

Screen Sharing

Twilio Video

// Twilio Video SDK does not directly provide an API for screen sharing
// Use navigator.mediaDevices.getDisplayMedia() and convert the stream to LocalVideoTrack

navigator.mediaDevices.getDisplayMedia().then(stream => {
return new TwilioVideo.LocalVideoTrack(stream.getVideoTracks()[0]);
});

// For more implementations, see:
// 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

Enable or disable local screen sharing with trtc.startScreenShare() and trtc.stopScreenShare(). When enabled, remote users receive the TRTC.EVENT.REMOTE_VIDEO_AVAILABLE event with streamType as TRTC.TYPE.STREAM_TYPE_SUB. Use trtc.startRemoteVideo() to pull the screen sharing stream.
For best practices, see Screen Sharing Best Practices.
// Local: After calling trtc.enterRoom()

// Enable local screen sharing
await trtc.startScreenShare();

// Disable local screen sharing
await trtc.stopScreenShare();
// Remote: Register event before calling trtc.enterRoom()

// Pull remote screen sharing stream
trtc.on(TRTC.EVENT.REMOTE_VIDEO_AVAILABLE, ({ userId, streamType }) => {
if (streamType === TRTC.TYPE.STREAM_TYPE_MAIN) {
// Main stream: user's camera video
trtc.startRemoteVideo({ userId, streamType, view: `${userId}_main` });
} else {
// Sub stream: user's screen sharing
trtc.startRemoteVideo({ userId, streamType, view: `${userId}_screen` });
}
})

trtc.enterRoom(roomConfig);

Audio/Video Encoding Configuration

Twilio Video

// Twilio Video SDK does not provide direct APIs for encoding configuration
// Use browser MediaTrackConstraints when calling connect()

const videoEncodingProfile = {
width: 1280,
height: 720,
frameRate: 24
};

const audioEncodingProfile = {
sampleRate: 16000
};

await TwilioVideo.connect(token, {
video: videoEncodingProfile,
audio: audioEncodingProfile
});

// For more implementations, see:
// https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackConstraints

Tencent RTC Engine

// Local: After calling trtc.enterRoom()

// Predefined video encoding profile
const videoEncodingProfile1 = {
option: {
profile: '1080p' // 1920x1080, 15fps, 2000kbps
}
}

// Custom configuration
const videoEncodingProfile2 = {
option: {
profile: {
width: 1920,
height: 1080,
frameRate: 15,
bitrate: 2200
}
}
}

await trtc.startLocalVideo(videoEncodingProfile1);

// Dynamically adjust with updateLocalVideo
await trtc.updateLocalVideo(videoEncodingProfile2);

// Local audio uplink configuration
await trtc.startLocalAudio({ option: { profile: TRTC.TYPE.AUDIO_PROFILE_STANDARD }});

Network Quality Monitoring

Twilio Video

// Twilio Video SDK uses the networkQuality parameter in connect() to set report granularity
await TwilioVideo.connect(token, {
networkQuality: {
local: 1, // Minimal, only reports local participant's quality
remote: 1 // Minimal, reports remote participants' quality
}
});

Tencent RTC Engine

After joining the room, monitor uplink/downlink network quality by registering the NETWORK_QUALITY event before entering. For more details, see Network Quality Detection Tutorial.
// Local: Register event before calling 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}`)
})

Custom Capture and Rendering

Twilio Video

// Twilio Video's LocalTrack supports passing an existing MediaStreamTrack for custom capture

const customStream = await someCustomCapture(); // e.g. canvas.captureStream(), WebCodecs …
const customMSTrack = customStream.getVideoTracks()[0]; // or getAudioTracks()[0]
const customTwilioTrack = new TwilioVideo.LocalVideoTrack(customMSTrack, { name: 'my_custom_track' });

const room = await TwilioVideo.connect(token, {
tracks: [ customTwilioTrack /* or customMsTrack */ ],
});

// For more implementations, see:
// https://developer.mozilla.org/en-US/docs/Web/API/MediaStreamTrack

Tencent RTC Engine

When calling trtc.startLocalAudio() or trtc.startLocalVideo(), pass the audioTrack or videoTrack parameter for custom MediaStreamTrack capture.
// Local: After calling trtc.enterRoom()

const customStream = await someCustomCapture(); // e.g. canvas.captureStream(), WebCodecs …
const customVideoMSTrack = customStream.getVideoTracks()[0];
const customAudioMSTrack = customStream.getAudioTracks()[0];


// Custom video capture
await trtc.startLocalVideo({ option: { videoTrack: customVideoMSTrack }});

// Custom audio capture
await trtc.startLocalAudio({ option: { audioTrack: customAudioMSTrack }});

Data Channel / Custom Message

Twilio Video

// Twilio Video uses LocalDataTrack objects for data channels and custom message transmission

const dataTrack = new TwilioVideo.LocalDataTrack();

const room = await TwilioVideo.connect(token, {
name: 'my_room',
tracks: [dataTrack /* and other tracks */ ]
});

// Send message locally
dataTrack.send('Hello!');

// Remote participants detect track type via track.kind, receive messages via 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);
});
}
});

// For more implementations, see:
// https://www.twilio.com/docs/video/using-datatrack-api

Tencent RTC Engine

Custom Message: trtc.sendCustomMessage() broadcasts messages to all users in the room.
SEI Message: trtc.sendSEIMessage() attaches SEI messages to video frames, suitable for time-sensitive scenarios like lyric sync or live quizzes.
// Local: After calling trtc.enterRoom()

// Send custom message
trtc.sendCustomMessage({
cmdId: 1,
data: new TextEncoder().encode('Hello!').buffer // Max 1KB per message
});

// Receive custom message via CUSTOM_MESSAGE event
trtc.on(TRTC.EVENT.CUSTOM_MESSAGE, event => {
// event.userId: sender's userId
// event.cmdId: custom message Id
// event.seq: message sequence number
// event.data: message content (ArrayBuffer)
console.log(`
received custom msg from ${event.userId},
message: ${new TextDecoder().decode(event.data)}
`);
});
// Send SEI message
// Enable SEI functionality when creating the instance
const trtc = TRTC.create({ enableSEI: true });

// Local: After enterRoom() and startLocalVideo(), send SEI message
try {
const unit8Array = new Uint8Array([1, 2, 3]);
trtc.sendSEIMessage(unit8Array.buffer);
// Message queued, waiting for next video frame.
} catch(error) {
console.error(error);
}

// Receive SEI message via SEI_MESSAGE event
trtc.on(TRTC.EVENT.SEI_MESSAGE, event =>
console.log(`
received SEI message from ${event.userId},
message: ${event.data}
`);
)

FAQs

What is the difference between Twilio Video's Access Token and TRTC's UserSig?

Both are time-sensitive credentials for client authentication, but their generation methods differ:
Twilio Access Token: Generated server-side using Account SID, API Key SID, and API Key Secret with Twilio SDK libraries.
TRTC UserSig: Generated server-side using SDKAppID and SDKSecretKey with HMAC SHA256.

How does Twilio's Room Name (string) map to TRTC's Room ID?

TRTC supports two types of room identifiers:
Numeric Room ID (roomId): Integer range 1 to 4294967294 (recommended).
String Room ID (strRoomId): Up to 64 bytes; supports letters, numbers, and select special characters.
If your Twilio project uses string room names, map them directly to strRoomId.
Note:
Within a single TRTC application, roomId and strRoomId cannot be mixed; they are not interoperable. If both are set in trtc.enterRoom(), roomId takes precedence.

Why does remote audio not require manual subscription in TRTC?

Twilio Video requires manual handling of remote audio via remoteParticipant.on('trackSubscribed'). In TRTC, remote audio streams are automatically played when the user joins the room. To control playback for a specific user, use muteRemoteAudio(userId, true/false).

More Information

Refer to the API Reference for a complete function list and descriptions. For more integration guidance, see Other Issues.