独立 RTC 频道
Flutter 的 im.channels 提供独立频道 API,复用 deeprespond_im_call 的 LiveKit 媒体。Android / iOS 可通过 Flutter 接入;这里没有独立 Swift IM SDK。服务端创建和授权见频道概述。
依赖与权限
使用包含频道 API 的同版本 deeprespond_im、deeprespond_im_flutter、deeprespond_im_call。媒体包随客户端创建注册提供方,无需设置 DRClientOptions.call。先按初始化创建并登录 im。
iOS Info.plist 配置 NSMicrophoneUsageDescription 与 NSCameraUsageDescription;Android 配置并处理麦克风 / 摄像头权限。默认不采集,用户拒绝权限时可保持只接收。subscriber 不允许发布,audio 频道不允许摄像头。
加入与退出
import 'package:deeprespond_im/deeprespond_im.dart';
import 'package:deeprespond_im_call/deeprespond_im_call.dart';
if (!im.channels.supported) throw StateError('当前环境没有频道媒体适配');
final cancel = DRCancelToken();
final channel = await im.channels.join('meeting-demo',
options: ChannelJoinOptions(ticket: ticketFromBusinessServer, cancel: cancel),
);
// join 成功表示媒体连接与 HTTP joined 确认完成。
await channel.setMicrophoneEnabled(true); // 在用户点击后调用。
await channel.setCameraEnabled(true); // 仅 video publisher。
final states = channel.stream.listen((snapshot) {
print(snapshot.session.status);
});
final tracks = channel.tracks.listen((items) {
// 完整的已授权轨道列表;sessionId 保持 String。
});
final localVideo = channel.localView();
// 实际远端 ID 来自授权 ChannelTrack.sessionId:
final remoteVideo = channel.remoteView(remoteSessionId);
await states.cancel();
await tracks.cancel();
await channel.leave();ticketFromBusinessServer 和 remoteSessionId 由业务授权响应及轨道提供;不要记录票据。开放频道省略 ticket。取消尚未完成的 join 调用 cancel.cancel();取得句柄后使用 leave。失败或晚到连接都会清理媒体,退出 HTTP 失败也停止本地采集。
API 与恢复
| API | 说明 |
|---|---|
supported、current | 本机媒体能力、本地当前句柄 |
getChannel(channelId) | 频道查询 |
getCurrentSession() | 本登录对应会话,无会话为 null |
listParticipants(channelId, cursor:, limit:) | 当前成员;需要有效频道会话 |
join(channelId, options:) | 新加入,默认不采集 |
resume(channelId:, sessionId:, cancel:) | 原会话恢复,不重新预留 |
final existing = await im.channels.getCurrentSession();
if (existing != null && ['joining', 'joined'].contains(existing.status)) {
final restored = await im.channels.resume(
channelId: existing.channelId, sessionId: existing.sessionId,
);
// 用户确认后才重新开启采集。
}句柄有 channelId、sessionId、snapshot、stream、tracks、currentTracks、refresh()、setMicrophoneEnabled()、setCameraEnabled()、leave()。状态和轨道流会先回放当前值。ChannelSnapshot 包含 channel、session、members、mediaState、error;客户端 ChannelChanged 事件反映当前句柄变化。
视频组件与生命周期
ChannelVideoView(channel:, local:, sessionId:, fit:, placeholder:) 支持本地或指定会话的视频;句柄扩展提供 localView()、remoteView(sessionId)、switchCamera()、setSpeakerphoneOn()。SDK 只暴露与 HTTP 授权成员精确匹配的轨道。
移除视频组件只解绑显示,离开页面仍需主动 leave。SDK 自动心跳 / 续凭据,并处理登出、登录切换、授权拒绝及会话到期;不能跨 IM 登录会话恢复。LiveKit 自身刷新连接 Token 不代表业务授权永久有效。
独立频道不自动显示 CallKit、系统来电 UI 或来电通知。后台持续采集的前台服务、iOS 后台音频和系统生命周期保障仍需专项开发及验收。本轮提供源码,尚未生成频道版本发布制品或完成真实设备互通。
