即时通信 IM 接入概览(Flutter)

这篇档提供 AtomicXCore 的完整集成指南,帮助开发者快速实现多人音视频房间功能。SDK 采用纯 API 架构设计,开发者可完全自定义 UI 界面,专注于业务逻辑和用户体验的实现。

相关产品
即时通信 IM 产品页,含版本规格、价格与购买入口。

一、核心功能

AtomicXCore 中用于搭建多人音视频房间场景所需要使用到的核心模块包含以下三个:

·RoomStore:房间管理功能入口,包含功能:预约房间、创建房间、加入房间、房间内呼叫等。

·RoomParticipantStore:房间内参与者功能入口, 包含功能:管理员设置、房主转移、移出房间、参与者设备控制等。

·RoomParticipantWidget:房间内参与者视频画面视图。

三、步骤1:开通服务

请参见 开通服务,获取体验版或付费版 SDK。

四、步骤2:环境准备

平台 版本
Flutter 3.29.3 及以上版本。
Android 最低兼容 Android 5.0 (SDK API Level 21)及以上版本。
iOS iOS 14.0 及更高。

五、步骤3:集成 AtomicXCore SDK

在你的工程 pubspec.yaml 文件中,添加 atomic_x_core 插件依赖。

dependencies: atomic_x_core: 最新版本

执行以下命令安装组件:

flutter pub get

六、步骤4:完成工程配置

·使用 Xcode 打开你的工程,选择项目 > Build Settings > Deployment,将其下的 Strip Style 设置为 Non-Global Symbols ,以保留所需要的全局符号信息。

·如你需要在 iOS 端使用音视频功能,需要授权麦克风和摄像头的使用权限(Android 端已在 SDK 中声明相关权限,你无需手动进行相关配置)。

在你 App 的 Info.plist(路径:ios/Runner/Info.plist)中添加以下两项,分别对应麦克风和摄像头在系统弹出授权对话框时的提示信息。

<key>NSCameraUsageDescription</key><string>TUIRoomKit 需要访问你的相机权限</string><key>NSMicrophoneUsageDescription</key><string>TUIRoomKit 需要访问你的麦克风权限</string>

完成以上添加后,在你的 ios/Podfile 中添加以下预处理器定义,用于启用相机与麦克风权限。

post_install do |installer| installer.pods_project.targets.each do |target| flutter_additional_ios_build_settings(target) target.build_configurations.each do |config| config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [ '$(inherited)', 'PERMISSION_MICROPHONE=1', 'PERMISSION_CAMERA=1', ] end endend

七、步骤5:实现登录逻辑

在你的项目中调用 LoginStore.shared.login 完成登录,这是使用 AtomicXCore 所有功能的关键前提。

注意:重要:

注意:推荐在你 App 自身的用户账户登录成功后,再调用 LoginStore.shared.login,以确保登录业务逻辑的清晰和一致。

import 'package:atomic_x_core/atomicxcore.dart';var loginResult = await LoginStore.shared.login( sdkAppID: 'SDKAPPID', // 替换为你的 SDKAPPID userID: 'userID', // 替换为你的 UserID userSig: 'userSig', // 替换为你的 UserSig);if (loginResult.isSuccess) { // login success} else { // login error}

登录接口参数说明:

参数 类型 说明
sdkAppId int 从 控制台 获取,通常是以 140 或 160 开头的 10 位整数。
userID String 当前用户的唯一 ID,仅包含英文字母、数字、连字符和下划线。为避免多端登录冲突,请勿使用 1、123 等简单 ID。
userSig String 用于腾讯云鉴权的票据。请注意:开发环境:你可以采用本地 GenerateTestUserSig.genTestSig 函数生成 userSig 或者通过 UserSig 辅助工具 生成临时的 UserSig。生产环境:为了防止密钥泄露,请务必采用服务端生成 UserSig 的方式。详细信息请参考 服务端生成 UserSig。更多信息请参见 如何计算及使用 UserSig。

九、步骤1:房主创建并加入房间

创建并加入房间具体流程如下,只需执行以下几步操作,即可快速搭建出多人房间。

注意:提示:

注意:房主创建并加入房间的业务代码,可以参考 GitHub 或者 CNB TUIRoomKit 开源项目中 room_main_widget.dart 文件来了解完整的实现逻辑。

十、一、创建并加入房间

实现方式:

1. 配置房间初始化参数:初始化 CreateRoomOptions 创建房间配置项设置房间名称,房间密码。

2. 房间权限预设:设置房间内全场成员权限,例如全体静音,全体禁画等。

3. 创建并加入房间:调用 RoomStore 的 createAndJoinRoom 接口执行核心操作。

示例代码:

import 'package:atomic_x_core/atomicxcore.dart';// RoomMainPage 代表房间主视图class RoomMainPage extends StatefulWidget { final String roomID; final RoomType roomType; const RoomMainPage({super.key, required this.roomID, required this.roomType}); @override State<RoomMainPage> createState() => _RoomMainPageState();}class _RoomMainPageState extends State<RoomMainPage> { @override void initState() { super.initState(); createAndJoinRoom(); } // 调用此方法完成创建并加入房间的复合操作 void createAndJoinRoom() async { // 1. 配置房间初始化参数 // CreateRoomOptions 用于定义房间的基础属性及初始权限控制 final options = CreateRoomOptions( roomName: '我的讨论会', // 设置房间对外展示的名称 password: '', // 设置房间进入密码(若无需密码则留空) // 2. 权限预设:在创建之初即可控制全场权限(通常用于正式会议场景) isAllCameraDisabled: false, // 全员开启/禁用摄像头的初始状态 isAllMessageDisabled: false, // 全员开启/禁言的初始状态 isAllMicrophoneDisabled: false, // 全员开启/静音的初始状态 isAllScreenShareDisabled: false, // 全员禁止/允许屏幕分享的初始状态 ); // 3. 创建并加入房间 // 该方法是一个复合操作:若房间不存在则先创建,随后自动执行加入流程 final result = await RoomStore.shared.createAndJoinRoom( roomID: widget.roomID, roomType: widget.roomType, options: options, ); if (result.isSuccess) { debugPrint('创建并加入房间成功'); } else { debugPrint('创建并加入房间失败 [错误码: ${result.errorCode}]: ${result.errorMessage}'); } } @override Widget build(BuildContext context) { return Container(); // 房间视图内容 }}

createAndJoinRoom 接口参数详细说明

参数名 类型 必填 说明
roomID String 是 字符串类型的房间唯一标识符。限制长度为 0-48 字节。建议仅包含数字、英文字母(区分大小写)、下划线(_)和连字符(-)。避免使用空格和中文字符。
roomType RoomType 是 房间类型standard:标准房间,所有成员可自由音视频互动。webinar:大型研讨会房间,区分嘉宾和观众角色,观众默认无上麦权限。
options CreateRoomOptions 是 房间创建选项配置对象。

CreateRoomOptions 结构体详细说明

参数名 类型 必填 默认值 说明
roomName String 否 "" 房间名称。若不设置,系统会使用默认名称。
password String 否 "" 房间密码。设置后,其他用户加入房间时需输入密码。
isAllMicrophoneDisabled bool 否 false 是否全员禁止开启麦克风。开启后,除房主/管理员外,普通参与者默认禁止打开麦克风。
isAllCameraDisabled bool 否 false 是否全员禁止开启摄像头。开启后,除房主/管理员外,普通参与者默认禁止打开摄像头。
isAllScreenShareDisabled bool 否 false 是否全员禁止发起屏幕共享。开启后,仅房主/管理员可进行屏幕共享。
isAllMessageDisabled bool 否 false 是否全员禁止发送聊天消息(禁言)。开启后,普通参与者无法在房间内发送文字消息。

十一、二、打开摄像头和麦克风

进房成功后调用 DeviceStore 单例对象的 openLocalCamera、openLocalMicrophone 接口打开本地设备。

import 'package:atomic_x_core/atomicxcore.dart';/// 打开设备/// 注意:Android 平台需要在开启前先申请摄像头和麦克风权限/// 可选择使用permission_handler库申请权限void _openDevices() { // 1. 打开前置摄像头 DeviceStore.shared.openLocalCamera(true); // 2. 打开麦克风 DeviceStore.shared.openLocalMicrophone();}

openLocalCamera 接口参数详细说明

参数名 类型 必填 默认值 说明
isFront bool 是 – 是否开启前置摄像头。

十二、3. 结束房间

当房主期望结束房间时,调用 RoomStore 的 endRoom 接口即可结束当前房间。结束房间后,房间内的所有参与者都会收到房间结束事件(onRoomEnded)。

import 'package:atomic_x_core/atomicxcore.dart';/// 调用此方法结束房间Future<void> endRoom() async { // endRoom 接口用于永久结束当前房间。 // 注意:通常该操作仅限房主(Owner)执行,执行后所有成员将被移出房间且音视频采集会强制停止。 final result = await RoomStore.shared.endRoom(); if (result.isSuccess) { debugPrint('结束房间成功'); } else { debugPrint('结束房间失败 [错误码: ${result.errorCode}]: ${result.errorMessage}'); }}

十三、步骤2:参与者加入房间

·参与者加入房间,通过简单几步操作,即可实现与房间内其他参与者进行实时音视频互动。

十四、一、加入房间

·参与者需要加入房间时,调用 RoomStore 的 joinRoom 接口,即可加入房间,此时房间内其他参与者会收到参与者加入房间事件通知(onParticipantJoined)。

import 'package:atomic_x_core/atomicxcore.dart';/// 调用此方法加入一个已存在的房间Future<void> joinRoom() async { // 调用 RoomStore 加入房间接口 // 该操作会验证房间是否存在、用户是否被禁入以及密码是否正确 final result = await RoomStore.shared.joinRoom( roomID: targetRoomID, // 目标房间 ID roomType: roomType, // 目标房间类型 password: roomPassword, // 房间密码,若房间未设置密码则传空字符串 ); if (result.isSuccess) { print("加入房间成功"); } else { print("加入房间失败 [错误码: ${result.errorCode}]: ${result.errorMessage}"); }}

joinRoom 接口参数详细说明

参数名 类型 必填 说明
roomID String 是 字符串类型的房间唯一标识符。限制长度为 0-48 字节。建议仅包含数字、英文字母(区分大小写)、下划线(_)和连字符(-)。避免使用空格和中文字符。
roomType RoomType 是 房间类型standard:标准房间,所有成员可自由音视频互动。webinar:大型研讨会房间,区分嘉宾和观众角色,观众默认无上麦权限。
password String 否 房间密码,空字符串 "" 通常表示该房间不设密码。限制长度为 0-32 字节。推荐使用 4-8 位纯数字,方便移动端输入。设置后,其他用户加入房间时需输入密码。建议不要存储明文敏感信息。

十五、二、打开摄像头和麦克风

代码示例可参考 打开摄像头和麦克风 步骤。

十六、三、离开房间

·当参与者要离开房间时,通过调用 RoomStore 的 leaveRoom 接口即可离开房间,此时房间内其他参与者都会收到参与者离开房间事件通知(onParticipantLeft)。

import 'package:atomic_x_core/atomicxcore.dart';/// 调用此方法主动退出当前房间Future<void> leaveRoom() async { // 1. 业务逻辑说明 // leaveRoom 接口用于普通成员或房主主动退出房间。 // 与 endRoom 不同,房主调用 leaveRoom 只会让自己离开,房间依然存在。 // 2. 调用 RoomStore 离开房间接口 // 该操作会停止音视频流传输,并通知服务器将当前用户移出房间 final result = await RoomStore.shared.leaveRoom(); if (result.isSuccess) { print("退出房间成功"); } else { print("退出房间失败 [错误码: ${result.errorCode}]: ${result.errorMessage}"); }}

十七、步骤3:绑定视频画面视图

AtomicXCore SDK 的 RoomParticipantWidget 组件为开发者提供了完整的视频画面渲染解决方案。该组件支持本地摄像头画面和远端参与者视频流的实时显示,集成过程简单高效。

注意:提示:

注意:RoomParticipantWidget 是用于渲染房间参与者视频流的核心视图组件,若需要更灵活的视频组件布局方式,请参考 GitHub 或者 CNB 开源项目中 room_widget.dart 文件来了解完整的实现逻辑。

十八、实现方式:

1. 数据层订阅:订阅 RoomParticipantStore.state.participantList,建立参与者状态的响应式监听。

2. 状态自动同步:参与者列表变更时,系统自动更新 participantList 状态数据。

3. 视图初始化:根据参与者数据实例化 RoomParticipantWidget,绑定视频渲染逻辑。

4. UI 集成:完成视图层级集成、布局配置和渲染激活。

十九、示例代码:

import 'package:atomic_x_core/atomicxcore.dart';final _controllers = <String, RoomParticipantController>{};final _participantStore = RoomParticipantStore.create(roomID);Widget build(BuildContext context) { // 使用 ValueListenableBuilder 订阅房间参与者列表状态 return ValueListenableBuilder<List<RoomParticipant>>( valueListenable: _participantStore.state.participantList, builder: (context, participants, _) { return GridView.builder( gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2), itemCount: participants.length, itemBuilder: (_, index) => _buildParticipantView(participants[index]), ); }, );}Widget _buildParticipantView(RoomParticipant participant) { // 初始化 RoomParticipantController 实例 final controller = _controllers.putIfAbsent( participant.userID, () => RoomParticipantController.create( streamType: VideoStreamType.camera, participant: participant, ), )..updateParticipant(participant) ..setActive(true); // 可见时设置活跃状态为 true,不可见时设为 false // 初始化 Widget 并添加到房间界面中 return RoomParticipantWidget(controller: controller);}

RoomParticipantController 构造接口参数详细说明

参数名 类型 描述
streamType VideoStreamType 需要显示渲染视频流类型。camera:摄像头流screen:屏幕分享流
participant RoomParticipant 实时的“参与者快照”,涵盖了从基础身份到业务状态、再到底层音视频设备权限的所有关键信息。

RoomParticipant 结构体参数详细说明:

参数名 类型 必填 默认值 说明
userID String 是 "" 用户的唯一标识符。
userName String 否 "" 用户的昵称。
avatarURL String 否 "" 用户头像的 URL 地址。
nameCard String 否 "" 用户在房间内的名片/备注名。
role ParticipantRole 否 .generalUser 成员角色:owner (房主)admin (管理员)generalUser (普通用户)
roomStatus RoomParticipantStatus 否 .scheduled 成员在房间中的业务状态:scheduled(已预约)inCalling(呼叫中)callTimeout(呼叫超时)callRejected(拒绝呼叫)inRoom(在房间中)
microphoneStatus DeviceStatus 否 .off 麦克风设备的开启/关闭状态:off(关闭)on(开启)
cameraStatus DeviceStatus 否 .off 摄像头设备的开启/关闭状态:off(关闭)on(开启)
screenShareStatus DeviceStatus 否 .off 屏幕共享状态:off(关闭)on(开启)
isMessageDisabled bool 否 false 是否被禁言。为 true 时无法发送聊天消息。
metaData Map<String, String> 否 {} 业务自定义扩展数据,随参与者状态同步。

20、步骤4:监听房间内事件

·进入房间完成后,通过调用 RoomStore 的 addRoomListener 可以订阅到 RoomListener 中与房间相关的被动事件。

import 'package:atomic_x_core/atomicxcore.dart';// RoomPage 代表房间主视图class RoomPage extends StatefulWidget { const RoomPage({super.key}); @override State<RoomPage> createState() => _RoomPageState();}class _RoomPageState extends State<RoomPage> { // 房间事件监听器 late final RoomListener _roomListener; @override void initState() { super.initState(); /// 创建监听器,设置各事件回调 _roomListener = RoomListener( onRoomEnded: (roomInfo) { print("房间已结束: ${roomInfo.roomName}"); // 可以在这里导航回首页 }, // … 处理其他 RoomListener 事件 … ); /// 调用此方法添加监听器,订阅房间被动事件 RoomStore.shared.addRoomListener(_roomListener); } @override void dispose() { // 调用此方法移除监听器,避免内存泄漏 RoomStore.shared.removeRoomListener(_roomListener); super.dispose(); }}

21、运行效果

通过完成以上搭建步骤,你将得到一个纯净的多人视频渲染房间,但没有任何 UI 交互。

运行效果 

22、丰富多人房间功能

为了满足对多人房间更多的需求,AtomicXCore SDK 还提供了以下功能来丰富多人房间场景。

多人房间功能 功能介绍 功能 Stores 实现指南
实现更新房间信息功能 房主可以更新房间内部分信息,例如:房间名称,房间密码。 RoomStore 房间管理
实现会中呼叫功能 房主或管理员可以呼叫其他未进入房间的用户进房。 RoomStore 会中呼叫
实现预定房间功能 可以提前预定好房间,支持设置房间开始时间,结束时间,添加参与者。 RoomStore 预定房间
实现房间内成员管理功能 房主可以对房间内其他参与者进行管理,如:设置管理员,移出参与者,对单个参与者音视频状态控制。 RoomParticipantStore 成员管理

23、API 文档

Store/Widget 功能描述 API 文档
RoomStore 房间全生命周期管理:创建并加入 / 加入 / 离开 / 结束房间 / 更新、获取房间信息 / 房间预约 / 呼叫房间外成员 / 监听房间内被动事件(例如房间解散,房间信息更新等)。 API 文档
RoomParticipantStore 房间内参与者管理:设置管理员 / 转移房主 / 获取参与者列表 / 移出房间 / 参与者设备控制(如关闭、邀请打开摄像头、麦克风等)/ 申请打开设备(例如申请打开摄像头、麦克风等)。 API 文档
RoomParticipantWidget 单个参与者视频画面展示视图。 API 文档
RoomParticipantController RoomParticipantWidget 的控制器,用于绑定和更新参与者信息 / 更新视频流类型 / 设置活跃状态等。 API 文档

25、问题1:RoomParticipantWidget 绑定了其他参与者信息,并正确设置了视频流类型,依然看不到视频画面?

·检查 setActive:请确保当前 RoomParticipantWidget 在屏幕中是可见状态,并正确调用 RoomParticipantWidget 的 setActive:true。

·检查 RoomParticipant:请确保 RoomParticipantWidget 中设置的 RoomParticipant 的 cameraStatus 状态是否为 on。

·检查网络:请检查设备网络连接是否正常。

26、问题2:iOS 在 release 下运行/打包后无法进房?

使用 Xcode 打开你的工程,选择项目 > Build Settings > Deployment,将其下的 Strip Style 设置为 Non-Global Symbols ,以保留所需要的全局符号信息。

27、联系我们

如果在接入或使用过程中有任何疑问或者建议,欢迎 联系我们 提交反馈。

赞 (0)
上一篇 4天前
下一篇 4天前