开播与收听(React Native)

最近更新时间:2026-04-22 11:09:01

我的收藏
本文档将帮助开发者使用 AtomicXCore SDKLiveListStateLiveSeatState 快速构建一个包含主播开播和观众进房功能的语聊房 App

准备工作

步骤1:开通服务

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

步骤2:在当前项目中导入 AtomicXCore

1. 安装组件:请在您的工程中执行以下脚本,添加 AtomicXCore 的相关依赖;
# 1. 安装语聊核心及原生构建工具 (必选)
npx expo install react-native-tuikit-atomic-x expo-dev-client expo-build-properties

#2. 安装 UI 适配与工具库 (建议)
npx expo install react-native-safe-area-context react-native-toast-message react-native-localize
2. 配置工程权限:打开项目根目录下的 app.json 文件,配置语聊需要用到的系统权限(麦克风,后台音频),您可以这样配置:
{
"expo": {
"name": "ExpoLive",
"slug": "ExpoLive",
// ... 其它设置项

"ios": {
// ... 其它设置项
"bundleIdentifier": "com.anonymous.ExpoLive",
"infoPlist": {
"NSMicrophoneUsageDescription": "This app requires access to your microphone for live streaming.",
"UIBackgroundModes": [
"audio"
]
}
},
"plugins": [
"react-native-localize",
[
"expo-build-properties",
{
"ios": {
"useFrameworks": "static"
}
}
]
]
}
}
3. 重新构建原生开发包:您刚刚引入了一个全新的包含了原生代码的库 AtomicXCore,必须在工程根目录下重新编译一次原生应用,把这些新的 C++/Java/Swift 代码打包进去;仅在首次集成或更新 SDK 版本时需要执行此步,日常开发只需执行步骤 4。
# 本地已有 Android 和 iOS 的开发环境,则执行
npx expo run:ios //保确已安装 CocoaPods
npx expo run:android

# 或者使用云打包重新生成开发版的安装包
npx eas build --profile development --platform all
4. 运行 app:在工程根目录下执行如下脚本,iOS 通过系统相机扫码跳转 app,Android 直接打开上一步安装的 app 直接扫码,后续的 JS 代码变更会自动热更新。
npx expo start

步骤3:完成登录

在您的项目中调用 LoginState 中的 login 方法完成登录,这是使用 AtomicXCore 所有功能的关键前提
重要:
推荐在您 app 自身的用户账户登录成功后,再调用 LoginState 中的 login 方法,以确保登录业务逻辑的清晰和一致。
import { useLoginState } from 'react-native-tuikit-atomic-x/lib/module/atomic-x/state/LoginState';

const { login } = useLoginState();

const handleLogin = () => {
login({
sdkAppID: 1400000001, // 替换为您的 SDKAppID
userID: "test_001", // 替换为您的 UserID
userSig: "xxxxxxxxxx" // 替换为您的 UserSig
});
}
登录接口参数说明:
参数
类型
说明
sdkAppID
number
控制台获取,通常是以 140160 开头的 10 位整数。
userID
string
当前用户的唯一 ID,仅包含英文字母、数字、连字符和下划线。为避免多端登录冲突,请勿使用 1123 等简单 ID
userSig
string
用于腾讯云鉴权的票据。请注意:
开发环境:您可以采用本地 GenerateTestUserSig.genTestSig 函数生成 userSig 或者 通过 UserSig 辅助工具 生成临时的 UserSig。
生产环境:为了防止密钥泄露,请务必采用服务端生成 UserSig 的方式。详细信息请参考 服务端生成 UserSig
更多信息请参见 如何计算及使用 UserSig

搭建语音聊天室

步骤1:实现房主创建语聊房

房主开播流程如下,只需执行以下操作,即可快速搭建语聊房。

1. 初始化麦位 State

在您的房主页面中,创建一个 LiveSeatState 实例。您需要监听响应式数据变化,以实时获取麦位数据来渲染您的 UI 界面。
import { useLiveSeatState } from 'react-native-tuikit-atomic-x/lib/module/atomic-x/state/LiveSeatState';

// 定义语聊房 ID(需要与后续 createLive 中使用的 liveID 保持一致)
// liveID 由开发者自定义,建议使用唯一标识符(如 UUID 或时间戳组合)
// 格式要求:仅支持英文字母、数字、下划线,长度不超过 64 个字符
const liveID = 'your_live_room_id'; // 替换为您的语聊房 ID

// 使用 liveID 获取 LiveSeatState 实例
const { seatList } = useLiveSeatState(liveID);

2. 打开麦克风

通过调用 DeviceStateopenLocalMicrophone 接口打开麦克风,示例代码如下:
import { useDeviceState } from 'react-native-tuikit-atomic-x/lib/module/atomic-x/state/DeviceState';

const { openLocalMicrophone } = useDeviceState();

const openMic = () => {
openLocalMicrophone();
};

3. 开始语聊

通过调用 LiveListStatecreateLive 接口开始语聊直播,完整示例代码如下:
import { useLiveListState } from 'react-native-tuikit-atomic-x/lib/module/atomic-x/state/LiveListState';

// 获取 LiveListState 实例
const { createLive } = useLiveListState();

const startLive = () => {
createLive({
liveInfo: {
liveID: liveID, // 设置语聊的房间 id
liveName: 'test', // 设置语聊的房间名称
keepOwnerOnSeat: true, // 配置主播始终在麦位上
isSeatEnabled: true,
seatLayoutTemplateID: 70, // 麦位布局模板(例如 70 为语聊麦位模板)
seatMode: 'APPLY', // 上麦模式,例如申请上麦
maxSeatCount: 10 // 最大麦位数
},
onSuccess: () => {
console.log('创建语聊房成功');
// 此处可进行页面跳转
},
onError: (error) => {
console.log('创建语聊房失败', error);
}
});
};
LiveInfo 参数说明:
参数名
类型
属性
描述
liveID
string
必填
语聊房的唯一标识符。
liveName
string
选填
语聊房的标题。
notice
string
选填
语聊房的公告信息。
isMessageDisable
boolean
选填
是否禁言(true:是,false:否)。
isPublicVisible
boolean
选填
是否公开可见(true:是,false:否)。
isSeatEnabled
boolean
选填
是否启用麦位功能(true:是,false:否)。
keepOwnerOnSeat
boolean
选填
是否保持房主在麦位上。
maxSeatCount
number
必填
最大麦位数量。
seatMode
string
选填
上麦模式(FREE:自由上麦,APPLY:申请上麦)。
seatLayoutTemplateID
number
必填
麦位布局模板 ID,70 表示语聊。
coverURL
string
选填
语聊房的封面图片地址。
backgroundURL
string
选填
语聊房的背景图片地址。
activityStatus
number
选填
语聊活动状态。
isGiftEnabled
boolean
选填
是否启用礼物功能(true:是,false:否)。

4. 构建麦位 UI 界面

通过 LiveSeatState 实例,监听 seatList 的变化,以实时获取麦位数据来渲染您的界面。您可以在主播页通过以下方式监听数据:
import React, { useEffect } from 'react';
import { useLiveSeatState } from 'react-native-tuikit-atomic-x/lib/module/atomic-x/state/LiveSeatState';

// 使用 liveID 获取 LiveSeatState 实例
const { seatList } = useLiveSeatState(liveID);

// 根据 displaySeats 去更新 UI
const displaySeats = React.useMemo(() => {
return Array.from({ length: 10 }, (_, i) => {
const foundSeat = (seatList || []).find(seat => seat.index === i) || {};
return {
...foundSeat,
displayIndex: i + 1, // UI 显示的序号 (1-10)
userId: foundSeat.userInfo?.userID || foundSeat.userId || null,
};
});
}, [seatList]);


5. 结束语聊

语聊结束后,房主可以调用 LiveListStateendLive 接口结束语聊,SDK 会处理停止推流和销毁房间的逻辑。
import { useLiveListState } from 'react-native-tuikit-atomic-x/lib/module/atomic-x/state/LiveListState';

const { endLive } = useLiveListState();

// 结束语聊
const handleEndLive = () => {
endLive({
onSuccess: () => {
console.log('结束语聊成功');
// 此处可进行页面跳转
},
onError: (error) => {
console.log('结束语聊失败', error);
}
});
}

步骤2:实现观众进入语聊房

观众进入房间流程如下,通过简单几步操作,即可实现观众进入语聊房

1. 初始化麦位 State

在您的观众页面中,创建 LiveSeatState 实例,并监听 seatList 的变化,以渲染麦位。
import { useLiveSeatState } from 'react-native-tuikit-atomic-x/lib/module/atomic-x/state/LiveSeatState';

// 定义语聊房 ID(需要与后续 joinLive 中使用的 liveID 保持一致)
const liveID = 'your_live_room_id'; // 替换为您的语聊房 ID

// 使用 liveID 获取 LiveSeatState 实例
const { seatList } = useLiveSeatState(liveID);

2. 进入语聊房

通过调用 LiveListStatejoinLive 接口加入语聊房,完整示例代码如下:
import { useLiveListState } from 'react-native-tuikit-atomic-x/lib/module/atomic-x/state/LiveListState';

// 获取 LiveListState 实例
const { joinLive } = useLiveListState();

// 加入语聊
const handleJoinLive = () => {
joinLive({
liveID: liveID, // 想要加入语聊房的 liveID
onSuccess: () => {
console.log('成功进入语聊房');
// 此处可进行页面跳转
},
onError: (error) => {
console.log('进入语聊房失败', error);
}
});
};

3. 构建麦位 UI 界面

观众构建麦位 UI 的流程与主播完全一致,请参考 主播构建麦位 UI 界面

4. 退出语聊房

观众退出语聊房时,需要调用 LiveListStateleaveLive 接口来退出。
import { useLiveListState } from 'react-native-tuikit-atomic-x/lib/module/atomic-x/state/LiveListState';

// 获取 LiveListState 实例
const { leaveLive } = useLiveListState();

// 退出语聊房
const handleLeaveLive = () => {
leaveLive({
liveID: liveID, // 您当前加入语聊房的 liveID
onSuccess: () => {
console.log('退出语聊房成功');
// 此处可进行页面跳转
},
onError: (error) => {
console.log('退出语聊房失败', error);
}
});
}

运行效果

完成上述步骤后,即可完成一个最基础的语聊直播场景。


功能进阶

实现麦上用户说话音浪

在语聊房场景中,一个常见的需求是当麦上用户说话时,在其头像上显示一个波浪动画,以提示全房间用户“谁在说话”,LiveSeatState 提供了 speakingUsers 数据流,专门用于实现此功能。

实现效果


在您构建的麦位 UI 界面中监听 speakingUsers 变化,并更新“正在说话”状态,代码示例如下:
import { useLiveSeatState } from 'react-native-tuikit-atomic-x/lib/module/atomic-x/state/LiveSeatState';

// 使用 liveID 获取 LiveSeatState 实例
const { speakingUsers } = useLiveSeatState(liveID);

useEffect(() => {
console.log('正在说话的人', speakingUsers);
// 用这个数据和之前监听的 seatList 进行匹配来更新 UI
}, [speakingUsers]);

API 文档

State
功能描述
API 文档
LiveListState
语音聊天室全生命周期管理:创建 / 加入 / 离开 / 销毁房间,查询房间列表,修改语音聊天室信息(名称、公告等),监听语音聊天室状态(例如被踢出、结束)。
DeviceState
音视频设备控制:麦克风(开关 / 音量),设备状态实时监听。
CoGuestState
观众连麦管理:连麦申请 / 邀请 / 同意 / 拒绝,连麦成员权限控制(麦克风),状态同步。
CoHostState
主播跨房连线:支持多布局模板(动态网格等),发起 / 接受 / 拒绝连线,连麦主播互动管理。
GiftState
礼物互动:获取礼物列表,发送 / 接收礼物,监听礼物事件(含发送者、礼物详情)。
BarrageState
弹幕功能:发送文本 / 自定义弹幕,维护弹幕列表,实时监听弹幕状态。
LikeState
点赞互动:发送点赞,监听点赞事件,同步总点赞数。
LiveAudienceState
观众管理:获取实时观众列表(ID / 名称 / 头像),统计观众数量,监听观众进出事件。
AudioEffectState
音频特效:变声(童声 / 男声)、混响(KTV 等)、耳返调节,实时切换特效。

常见问题

听众调用 joinLive 后为什么没有声音?

检查设备权限:请确保 App 已获得麦克风的系统使用权限。
检查房主端:请确认房主端已正常调用 openLocalMicrophone() 以打开麦克风。
检查网络:请检查设备网络连接是否正常。

iOS 在 endLive 时 Crash?

现象: Expo 工程 iOS 端调用 endLive 时 App 瞬间闪退(Crash)。
根本原因: expo-modules-core 通过 KVO 监听视频流属性(尺寸、帧率)。流销毁瞬间属性回退为 -1。由于底层代码缺乏边界校验,-1 被作为参数传递给内存分配函数。在 iOS 环境下,-1 隐式转换为无符号整数(UInt64/size_t),数值膨胀为 $2^{64}-1$(即 $18,446,744,073,709,551,615$),诱发系统级 OOM(内存溢出)强杀。
【AI 执行指令】—— 请将以下任务复制发给 AI:
任务:修复 expo-modules-core 因 UInt 溢出导致的内存分配崩溃
1. 代码检索(Scan): 请深入扫描 node_modules/expo-modules-core 目录下的原生代码(重点关注 Objective-C、Swift 或 C++ 文件)。寻找通过 KVO (observeValueForKeyPath) 监听视频流状态(关键词:video, width, height, frameRate, buffer)的逻辑。
2. 定位逻辑: 找到获取上述属性值后,将其直接或间接传递给内存分配函数(如 malloc, realloc, calloc, 或 CMSampleBufferCreate)的代码位置。
3. 实施防御性修复: 在分配内存的操作前,必须增加边界校验。
要求: 检查属性值是否为负数(特别是 -1)。
逻辑: 若检测到非法值,应立即阻断分配流程(Early Return),或将该值强制重置为安全值(如 0),确保不会触发超大内存申请。
4. 工程化持久化: 修复代码后,请自动执行以下操作:
运行 npx patch-package expo-modules-core 生成补丁。
检查 package.json 的 scripts 中是否包含 "postinstall": "patch-package",若无则添加,确保修复对全团队生效。