Quick Start
This guide walks you through integrating @tencent-classroom/sdk — implementing the complete flow of creating an instance, joining a classroom, and leaving.
Requirements
- Node.js >= 16
- Modern browser with ES Module support (Chrome 85+ / Edge 86+ / Safari 15+ / Firefox 80+)
- WebRTC support required for audio/video features
Installation
bash
pnpm add @tencent-classroom/sdk
# or
npm install @tencent-classroom/sdkClassroom Lifecycle Overview
Basic Usage
Step 1: Import the SDK
typescript
import {
TencentClassroom,
TEvent,
StreamType,
JoinProgress,
} from '@tencent-classroom/sdk';Step 2: Create an Instance
typescript
const classroom = new TencentClassroom({
language: 'en', // UI language: zh-CN | zh-TW | en | ja | ko | vi | ar | id | es
debug: true, // Enable debug logging
board: {
domId: 'board-container', // Whiteboard mount container DOM ID
},
behavior: {
autoLoadDefaultDocument: true, // Auto-load default courseware after joining
},
});Tip: After
new TencentClassroom(), access the instance anywhere viaTencentClassroom.instance.
Step 3: Initialize the Engine
typescript
const initResult = await classroom.init();
if (!initResult.ok) {
console.error('SDK initialization failed:', initResult.message);
return;
}Step 4: Join a Classroom
typescript
const joinResult = await classroom.joinClass({
classId: 123456, // Classroom ID (required)
userId: 'user_001', // User ID (required)
token: 'biz-token-xxx', // Business token (required, issued by server)
});
if (!joinResult.ok) {
console.error('Join failed:', joinResult.message);
return;
}Step 5: In-class Interactions (Audio/Video / Remote Streams)
typescript
// Start local camera (pass a DOM container for preview)
await classroom.startCamera(document.getElementById('local-video')!);
// Start microphone
await classroom.startMicrophone();
// Bind a remote user's camera stream to a DOM element
const binding = classroom.bindRemoteView(
'teacher_001',
document.getElementById('remote-video')!,
StreamType.Camera,
);Step 6: Leave and Destroy
typescript
// Unbind remote streams
classroom.unbindRemoteView(binding);
// Leave the classroom
await classroom.leaveClass();
// Destroy the instance (releases all resources)
await classroom.destroy();Complete Minimal Example
typescript
import { TencentClassroom, TEvent, StreamType } from '@tencent-classroom/sdk';
async function main() {
// 1. Create instance
const classroom = new TencentClassroom({
language: 'en',
debug: true,
board: { domId: 'board-container' },
});
// 2. Initialize
const initResult = await classroom.init();
if (!initResult.ok) return console.error(initResult.message);
// 3. Listen to key events (set up before joining)
classroom.on(TEvent.KICK_OUT, ({ message }) => alert(message));
// 4. Join classroom
const joinResult = await classroom.joinClass({
classId: 123456,
userId: 'user_001',
token: 'your-token',
});
if (!joinResult.ok) return console.error(joinResult.message);
// 5. Start local audio/video
await classroom.startCamera(document.getElementById('local-video')!);
await classroom.startMicrophone();
// 6. Render remote stream
const binding = classroom.bindRemoteView(
'teacher_001',
document.getElementById('remote-video')!,
StreamType.Camera,
);
// 7. Leave on page unload
window.addEventListener('beforeunload', async () => {
classroom.unbindRemoteView(binding);
await classroom.leaveClass();
await classroom.destroy();
});
}
main();Advanced: JoinProgress Phases
The SDK executes 10 internal phases sequentially when joining. Subscribe to joinProgress$ to drive a Loading UI:
typescript
classroom.state.joinProgress$.subscribe((progress) => {
updateLoadingUI(progress);
});| Phase | Value | Description |
|---|---|---|
| Idle | idle | Initial state |
| FetchingSchoolInfo | fetchingSchoolInfo | Fetching school info (package, watermark config) |
| FetchingClassInfo | fetchingClassInfo | Fetching classroom details (type, config, members) |
| JoiningMember | joiningMember | Registering member (member/join) |
| LoginIM | loginIM | Logging into IM message channel |
| JoinIMGroup | joinIMGroup | Joining IM group (signaling + chat) |
| JoinTRTC | joinTRTC | Joining TRTC room (audio/video channel) |
| InitBoard | initBoard | Initializing whiteboard |
| InitPermission | initPermission | Fetching permission list |
| FetchingHistory | fetchingHistory | Fetching history messages |
| Completed | completed | Join complete |
Advanced: Runtime Environment Check
checkEnvironment() validates every core capability required by the classroom in a single call: browser environment, secure context (HTTPS / localhost), the mediaDevices API, and WebRTC support. Call it after init() and before joinClass().
typescript
const env = await classroom.checkEnvironment();
if (!env.ok) {
alert(env.message);
return;
}
if (!env.data.isSupported) {
// Use `reasons` to render fine-grained UI prompts
if (env.data.reasons?.includes('InsecureContext')) {
alert('Please open this page over HTTPS.');
} else if (env.data.reasons?.includes('WebRTCUnsupported')) {
alert('This browser does not support audio/video. Please use Chrome 85+ or Edge 86+.');
} else if (env.data.reasons?.includes('NoMediaDevices')) {
alert('mediaDevices API is unavailable in the current runtime.');
} else {
alert('The current environment does not support the classroom.');
}
return;
}
// env.data.checks exposes per-item results for diagnostics
// { browser: true, secureContext: true, mediaDevices: true, webrtc: true }Advanced: State Subscriptions & Event Listeners
Reactive State
typescript
// Subscribe to class status
classroom.state.classStatus$.subscribe(status => {
console.log('Class status:', status); // 'notStarted' | 'started' | 'ended' | 'expired'
});
// Listen for kick-out
classroom.on(TEvent.KICK_OUT, ({ reason, message }) => {
alert(message);
});
// Listen for member join
classroom.on(TEvent.MEMBER_JOIN, (member) => {
console.log('Member joined:', member.userId, member.nickName);
});Advanced Event Usage
typescript
// on returns an unsubscribe function
const off = classroom.on(TEvent.CLASS_START, () => console.log('Class started'));
off(); // Unsubscribe
// once — one-time listener, auto-removed after trigger
classroom.once(TEvent.JOIN_CLASS, (classInfo) => {
console.log('Joined, class name:', classInfo.className);
});
// waitFor — Promise-based, waits for one occurrence
const classInfo = await classroom.waitFor(TEvent.JOIN_CLASS);
// waitFor with timeout
try {
await classroom.waitFor(TEvent.BOARD_READY, 10_000);
} catch {
console.error('Timed out waiting for whiteboard');
}Advanced: Role-based Flows
Teacher
Student
Assistant
- Has the same management permissions as the teacher
- On-stage by default after joining — can open audio/video immediately
- Not recommended to call startCamera() + startMicrophone() by default
- Can perform all member management operations (kick, invite on-stage, etc.)
Supervisor
- Read-only mode: can watch audio/video, view whiteboard, browse member list
- Cannot send messages or manage members
- Not visible to other participants (does not appear in member list)
Advanced: Platform Detection
Access runtime environment info via classroom.platform:
typescript
classroom.platform.isMobile // Mobile (Native + Web)
classroom.platform.isDesktop // Desktop (Electron + Web desktop)
classroom.platform.isElectron // Electron desktop app
classroom.platform.isAndroid // Android
classroom.platform.isIOS // iOS
classroom.platform.isPad // Tablet (iPad / Android tablet)
classroom.platform.isWeb // Pure web browser
classroom.platform.isNative // Has Bridge injection (Electron / Android / iOS)
classroom.platform.supportTouch // Touch screen supported
// High-level classification
classroom.platform.platform // 'web' | 'electron' | 'android' | 'ios' | 'mobile-web' | 'server'
// Example: branching by platform
if (classroom.platform.isMobile) {
// Use mobile layout
} else {
// Use desktop layout
}Next Steps
- Audio & Video Guide — Device management, remote rendering, stage on/off
- IM Chat Guide — Sending and receiving messages
- Whiteboard Guide — Whiteboard and courseware operations
- Internationalization — Multi-language and key overrides
- Error Handling — TResult pattern explained
- API Reference — Complete API documentation