獨立 RTC 頻道
im.channels 讓已登入的使用者加入你的服務端建立的音影片頻道,用於會議、語音房這類不依賴 IM 群的場景,不需要好友關係或群。頻道的規則和開通條件見服務端文件獨立 RTC 頻道。
確認 SDK 版本
頻道 API 已在原始碼中提供,使用前請確認你安裝的 SDK 版本包含下面的介面。SDK 的釋出和真機驗收狀態見平臺與版本。
| 要做什麼 | 看哪裡 |
|---|---|
| 加入頻道、開啟麥克風和攝像頭 | 加入與採集 |
| 把其他成員的畫面和聲音顯示在頁面上 | 顯示授權媒體 |
| 頁面重新整理後回到原來的頻道 | 查詢與恢復 |
| 顯示頻道狀態、處理成員進出和頻道關閉 | 狀態、事件與收尾 |
| 在 React、Vue 中使用 | 框架繫結 |
加入與採集
下面的 im 是已登入的客戶端,ticketFromBusinessServer 是你的服務端發給這個使用者的票據。加入 open 頻道時不傳 ticket。
if (!im.channels.supported) throw new Error('当前环境不支持频道媒体');
const cancelJoin = new AbortController();
const channel = await im.channels.join('meeting-demo', {
ticket: ticketFromBusinessServer,
signal: cancelJoin.signal,
});
const stopState = channel.subscribe(() => {
const snapshot = channel.getSnapshot();
console.log(snapshot.session.status, snapshot.media_state);
});
// 在用户点击采集按钮后调用;默认麦克风、摄像头关闭。
await channel.setMicrophoneEnabled(true);
// 仅 video 频道的 publisher 可以开启摄像头。
await channel.setCameraEnabled(true);
// 页面离开时:先取消订阅,再退出。
stopState();
await channel.leave();join() 的引數:頻道 ID 加選項,或一個包含 channel_id 的物件。
| 選項 | 說明 |
|---|---|
ticket | 票據,ticket 頻道必填 |
client_session_id | 這次加入的 ID。省略時 SDK 自動生成,並在重試同一次加入時保持不變;自己提供時也必須保持不變 |
signal | AbortSignal,用來取消還沒完成的加入 |
microphoneEnabled、cameraEnabled | 加入時是否開啟麥克風、攝像頭,預設都關閉 |
什麼時候算加入成功:媒體已經連上、服務端確認會話為 joined 後,join() 才兌現。從加入到入會(準備房間、連線媒體、服務端確認)總共只有 60 秒,SDK 的重試不會重新計時。
取消和失敗:cancelJoin.abort() 取消還沒完成的加入;已經拿到控制代碼的,呼叫 leave() 退出。加入失敗、超時或被取消時,SDK 釋放預留的席位並停止本地的麥克風和攝像頭。
環境要求:
- 頁面為 HTTPS 或
localhost,瀏覽器支援 WebRTC,使用者允許使用麥克風和攝像頭,網路能連到媒體服務地址。 - 開啟麥克風、攝像頭和播放聲音都要由使用者的點選觸發。使用者拒絕許可權時,可以只看和聽、不發言。
- 訂閱者(
subscriber)不能開啟麥克風和攝像頭,audio頻道不能開啟攝像頭。 supported為true只說明當前瀏覽器有媒體能力,不代表應用已經開通頻道或使用者已經授權裝置。
顯示授權媒體
SDK 透過 track 事件把成員的音影片軌道交給你,用 session_id 和 username 標識成員。不要把媒體房間中的 identity 當作使用者名稱,session_id 也不要轉成 JavaScript 的 number。
const container = document.querySelector('#channel-media')!;
const players = new Map<string, HTMLMediaElement>();
const offTrack = channel.on('track', ({ session_id, kind, track, local }) => {
if (local && kind === 'audio') return; // 避免播放本机麦克风回声。
const key = `${session_id}:${kind}`;
players.get(key)?.remove();
const player = document.createElement(kind === 'video' ? 'video' : 'audio');
player.autoplay = true;
player.muted = local;
if (player instanceof HTMLVideoElement) player.playsInline = true;
player.srcObject = new MediaStream([track]);
container.append(player);
players.set(key, player);
void player.play().catch(() => {
// 显示“点击播放”按钮,并在用户操作中再次调用 player.play()。
});
});
const offRemoved = channel.on('trackRemoved', ({ session_id, kind }) => {
const key = `${session_id}:${kind}`;
const player = players.get(key);
if (player) { player.srcObject = null; player.remove(); }
players.delete(key);
});
// 页面卸载时执行:
offTrack();
offRemoved();
for (const player of players.values()) { player.srcObject = null; player.remove(); }
players.clear();
await channel.leave();只有透過 HTTP 介面加入、並且確認已連上媒體的成員,他的軌道才會交給你。成員名單還沒確認、成員已退出或授權被撤銷時,請移除對應的畫面,不要繼續顯示舊的畫面。
查詢與恢復
| 方法 / 屬性 | 說明 |
|---|---|
supported | 當前瀏覽器是否有媒體能力 |
current | 本頁面當前的頻道控制代碼 |
getChannel(id) / get(id) | 查詢你能看到的頻道 |
getCurrentSession() / currentSession() | 查詢本次登入在服務端的頻道會話,沒有時為 null |
listParticipants(id, page?) / members(id, page?) | 查詢頻道成員;需要你在這個頻道中有有效的會話 |
join(id, options?) | 加入頻道 |
resume({channel_id, session_id, signal?}) | 重新連線原來的會話:不重新佔用席位,也不自動開啟麥克風和攝像頭 |
頁面重新整理後,查到會話還在就恢復它:
const existing = await im.channels.getCurrentSession();
if (existing && ['joining', 'joined'].includes(existing.status)) {
const restored = await im.channels.resume({
channel_id: existing.channel_id,
session_id: existing.session_id,
});
// 用户确认后才重新开启采集。
}- 只能恢復本次登入的會話,不能恢復其他登入(其他裝置)的。
- 會話為
leaving時等它退出完成;為left時已經結束,需要重新加入。 - 不要把票據、控制代碼和媒體 Token 存進
localStorage或寫進日誌。
狀態、事件與收尾
channel.getSnapshot() 返回頻道當前的狀態:channel(頻道)、session(本人的會話)、members(成員)、media_state(媒體狀態)和 error(錯誤);用 channel.subscribe() 訂閱變化。控制代碼還提供 refresh()、麥克風和攝像頭的開關,以及 leave()。
| 控制代碼事件 | 載荷 | 什麼時候觸發 |
|---|---|---|
track、trackRemoved | session_id、username、kind、track、local | 成員的音影片軌道可用、不再可用 |
participantJoined、participantLeft | 成員 | 有人加入、離開 |
sessionLeaving、sessionLeft | 本人的會話 | 你開始退出、退出完成 |
channelClosing、channelClosed | 頻道 | 頻道開始關閉、關閉完成 |
connectionChanged | connecting、connected、reconnecting、disconnected | 媒體連線的狀態變化 |
客戶端事件 channel.changed 在本頁面當前的頻道控制代碼變化時觸發。React、Vue 中的 useChannel 見框架繫結。
SDK 自動處理的:心跳、續發媒體憑據;頁面解除安裝或被瀏覽器凍結(pagehide、freeze 事件)、退出登入和銷燬客戶端時退出頻道。只是最小化視窗不算離開頁面。
你需要處理的:
- 路由切換、元件解除安裝時主動呼叫
leave()。即使退出的請求失敗,本地的媒體也會停止;服務端可能還要一會兒才釋放席位。 - 只有發起加入的那個頁面持有媒體,其他標籤頁不會接管。
- 遇到忙線、封禁或授權被拒絕時,不要換一個新的
client_session_id反覆加入。錯誤碼見頻道錯誤碼。
