Atomicx 是腾讯云推出的音视频业务全新原子化接入方案。它将复杂的音视频房间功能拆解为独立的数据逻辑(State Hooks)与 UI 组件,旨在帮助开发者灵活可控的将多人音视频控制、屏幕共享、互动聊天等能力集成到业务系统中。本文将引导开发者使用 Atomicx 快速实现多人音视频房间的基础能力。

核心能力
通过 Atomicx,您可以快速获得构建专业多人音视频场景所需的完整能力。
多人房间管理:支持房间预约、创建、加入、及向特定用户发起房间邀请呼叫。
音视频通话:支持多人实时音视频通信及布局动态切换(例如九宫格、演讲者模式)。
屏幕共享:提供全屏内容共享及系统音频采集能力。
成员与权限管理:包含成员列表展示、角色转移(房主/管理员)及禁言/禁画等控场功能。
视觉增强:集成基础美颜(磨皮/美白)及虚拟背景(背景模糊/图片替换)功能。
互动聊天:支持房间内发送文本、表情消息及消息撤回、删除操作。
准备工作
步骤1:开通服务
步骤2:环境准备
Node.js: ≥ 18.19.1 (推荐使用官方 LTS 版本)。
Vue: ≥ 3.4.21。
现代浏览器:支持 WebRTC APIs 的现代浏览器。
设备:摄像头、麦克风、扬声器。
步骤3:安装 Atomicx 依赖
npm install tuikit-atomicx-vue3 @tencentcloud/uikit-base-component-vue3
pnpm install tuikit-atomicx-vue3 @tencentcloud/uikit-base-component-vue3
yarn add tuikit-atomicx-vue3 @tencentcloud/uikit-base-component-vue3
搭建基础多人房间
步骤1:配置全局 UIKitProvider
在
App.vue 中配置全局 UIKitProvider,这是使用 Atomicx 组件的基础。// src/App.vue<template><UIKitProvider theme="light" language="zh-CN"><!-- 您项目的 Dom 节点 --></UIKitProvider></template><script>import { UIKitProvider } from '@tencentcloud/uikit-base-component-vue3';</script>
步骤2:登录与身份鉴权
在进行身份鉴权前,您需要准备以下信息:
SDKAppID:从腾讯云 控制台 获取,通常是以 140 或 160 开头的 10 位整数。
userId:当前用户的唯一 ID,仅包含英文字母、数字、连字符和下划线。为避免多端登录冲突,请勿使用 1、123 等简单 ID。
userSig:用于腾讯云鉴权的票据。开发测试阶段,您可以通过 UserSig 辅助工具 快速生成临时 userSig。
注意:
在
components 目录下创建 LoginUserInfo.vue 组件,拷贝以下代码实现并填入您自己的 SDKAppID 信息。<template><div class="login-user-info-container"><template v-if="loginUserInfo"><div class="login-userid">用户 Id: {{ loginUserInfo.userId }}</div><div class="login-userid">用户名称: {{ loginUserInfo.userName }}</div><TUIButton type="primary" @click="handleLogout">退出登录</TUIButton></template><template v-else><TUIInput style="max-width: 200px;" v-model="userId" placeholder="请输入 userId" /><TUIInput style="max-width: 200px;" v-model="userName" placeholder="请输入 userName" /><TUIInput style="max-width: 200px;" v-model="userSig" :maxLength="1000" placeholder="请输入 userSig" /><TUIButton type="primary" @click="handleLogin">登录</TUIButton></template></div></template><script setup>import { ref, onMounted } from 'vue';import { TUIInput, TUIButton } from '@tencentcloud/uikit-base-component-vue3';import { useLoginState } from 'tuikit-atomicx-vue3';const { loginUserInfo, login, logout, setSelfInfo } = useLoginState();const SDKAppID = 1400704311; // TODO: 请替换为您的 SDKAppID,从腾讯云控制台获取const userId = ref('');const userName = ref('');const userSig = ref('');async function handleLogin() {console.log('userId.value', userId.value);console.log('userSig.value', userSig.value);if (userId.value) {await login({sdkAppId: SDKAppID,userId: userId.value,userSig: userSig.value,});sessionStorage.setItem('atomicx-demo-loginUserInfo', JSON.stringify(loginUserInfo.value));}if (userName.value) {await setSelfInfo({userName: userName.value,avatarUrl: '',});}}async function handleLogout() {await logout();sessionStorage.removeItem('atomicx-demo-loginUserInfo');}onMounted(() => {let loginUserInfo = sessionStorage.getItem('atomicx-demo-loginUserInfo');if (loginUserInfo) {loginUserInfo = JSON.parse(loginUserInfo);userId.value = loginUserInfo.userId;handleLogin();}});</script><style scoped>.login-user-info-container {display: flex;align-items: center;gap: 12px;}.login-userid {font-size: 14px;color: #666;}</style>
步骤3:创建或加入房间
在您项目的
src/components 目录下创建 RoomControl.vue 文件并拷贝以下代码实现创建/加入房间,离开/销毁房间能力。<template><div class="room-control-container"><div v-if="currentRoom">房间 Id: {{ currentRoom?.roomId }}</div><div v-if="currentRoom">房间名称: {{ currentRoom?.roomName }}</div><TUIInput v-if="!currentRoom" style="max-width: 200px;" v-model="roomId" placeholder="请输入房间 ID" /><TUIButton v-if="!currentRoom" type="primary" @click="handleCreateRoom">创建房间</TUIButton><TUIButton v-if="!currentRoom" type="primary" @click="handleJoinRoom">加入房间</TUIButton><TUIButton v-if="currentRoom && localParticipant?.role === RoomParticipantRole.Owner" type="primary" @click="handleEndRoom">结束房间</TUIButton><TUIButton v-if="currentRoom" type="primary" @click="handleLeaveRoom">离开房间</TUIButton></div></template><script setup>import { ref, watch } from 'vue';import { TUIInput, TUIButton, TUIToast } from '@tencentcloud/uikit-base-component-vue3';import { useLoginState, useRoomState, useRoomParticipantState, TUIErrorCode, RoomParticipantRole } from 'tuikit-atomicx-vue3/room';const { loginUserInfo } = useLoginState();const { currentRoom, createAndJoinRoom, joinRoom, endRoom,leaveRoom } = useRoomState();const { localParticipant, getParticipantList } = useRoomParticipantState();const roomId = ref('');async function handleCreateRoom() {try {await createAndJoinRoom({roomId: roomId.value,options: {roomName: `${loginUserInfo.value.userName || loginUserInfo.value.userId}的临时房间`,},});TUIToast.success({ message: '创建房间成功' });} catch (error) {if (error.code === TUIErrorCode.ERR_ROOM_ID_OCCUPIED) {TUIToast.error({ message: '房间已存在, 请重新输入房间 ID' });} else {TUIToast.error({ message: '创建房间失败,请重试' });}}}async function handleJoinRoom() {try {await joinRoom({roomId: roomId.value,});TUIToast.success({ message: '加入房间成功' });} catch (error) {TUIToast.error({ message: '加入房间失败,请重试' });}}async function handleEndRoom() {try {await endRoom();TUIToast.success({ message: '结束房间成功' });} catch (error) {TUIToast.error({ message: '结束房间失败,请重试' });}}async function handleLeaveRoom() {try {await leaveRoom();TUIToast.success({message: '离开房间成功'});} catch (error) {TUIToast.error({ message: '离开房间失败,请重试' });}}watch(() => currentRoom.value?.roomId, (val, oldVal) => {if (!oldVal && val) {getParticipantList({ cursor: '' });}});</script><style scoped>.room-control-container {display: flex;align-items: center;gap: 12px;padding: 16px;background: white;border: 1px solid #e5e5e5;border-radius: 8px;flex: 1;min-width: 300px;}.room-control-container > div {font-size: 14px;color: #666;white-space: nowrap;}</style>
步骤4:采集媒体设备
在您项目的
src/components 目录下创建 DeviceControl.vue 文件并拷贝以下代码实现音视频媒体采集能力。<template><div class="device-control-container"><TUIButton v-if="!isLocalCameraOpen" type="primary" @click="openLocalCamera">打开摄像头</TUIButton><TUIButton v-if="isLocalCameraOpen" type="primary" @click="closeLocalCamera">关闭摄像头</TUIButton><TUIButton v-if="!isLocalMicrophoneOpen" type="primary" @click="openLocalMicrophone">打开麦克风</TUIButton><TUIButton v-if="isLocalMicrophoneOpen" type="primary" @click="closeLocalMicrophone">关闭麦克风</TUIButton></div></template><script setup>import { computed } from 'vue';import { TUIButton } from '@tencentcloud/uikit-base-component-vue3';import { useDeviceState, DeviceStatus } from 'tuikit-atomicx-vue3/room';const { microphoneStatus, cameraStatus, openLocalCamera, openLocalMicrophone, closeLocalCamera, closeLocalMicrophone } = useDeviceState();const isLocalCameraOpen = computed(() => cameraStatus.value === DeviceStatus.On);const isLocalMicrophoneOpen = computed(() => microphoneStatus.value === DeviceStatus.On);</script><style scoped>.device-control-container {display: flex;align-items: center;gap: 12px;padding: 16px;background: white;border: 1px solid #e5e5e5;border-radius: 8px;flex: 1;min-width: 300px;}</style>
步骤5:渲染视频布局
在您项目的
src/components 目录下创建 RoomMain.vue 文件并拷贝以下代码实现音视频流渲染能力。<template><div class="room-main-container"><RoomView v-if="currentRoom?.roomId"><template #participantViewUI="{ participant, streamType }"><div :class="['participant-view-container', { 'camera-off': isCameraOff(participant) }]"><Avatarv-if="isCameraOff(participant)"class="avatar-region"size="xxl":src="participant.avatarUrl":user-id="participant.userId"/><div class="user-info-container"><div v-if="!isScreen(streamType)"><IconMicOff v-if="isMicriophoneOff(participant)" size="20"/><IconMicOn v-else size="20" /></div><span>{{ participant.userName || participant.userId }}</span></div></div></template></RoomView><div v-else class="empty-state"><div class="empty-content"><h3 class="empty-title">暂未加入房间</h3><p class="empty-description">请在上方创建房间或加入已有房间</p></div></div></div></template><script setup>import { IconMicOff, IconMicOn } from '@tencentcloud/uikit-base-component-vue3';import { RoomView, Avatar, DeviceStatus, VideoStreamType, useRoomState } from 'tuikit-atomicx-vue3/room';const { currentRoom } = useRoomState();const isCameraOff = (participant) => participant.cameraStatus !== DeviceStatus.On;const isMicriophoneOff = (participant) => participant.microphoneStatus !== DeviceStatus.On;const isScreen = (streamType) => streamType === VideoStreamType.Screen;</script><style scoped>.room-main-container { flex: 1; display: flex; background: white; border: 1px solid #e5e5e5; border-radius: 8px; overflow: hidden; min-height: 0;}.participant-view-container { position: absolute; width: 100%; height: 100%; display: flex; flex-direction: column; justify-content: center; align-items: center; background: transparent; &.camera-off { background: #f0f0f0; }}.avatar-region { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);}.user-info-container { position: absolute; bottom: 12px; left: 12px; height: 32px; gap: 6px; max-width: calc(100% - 24px); background: rgba(0, 0, 0, 0.75); color: white; font-size: 13px; border-radius: 16px; display: flex; align-items: center; padding: 0 12px;}.empty-state { flex: 1; display: flex; align-items: center; justify-content: center; padding: 40px;}.empty-content { text-align: center; max-width: 320px;}.empty-icon { width: 80px; height: 80px; color: #d1d5db; margin: 0 auto 24px;}.empty-title { margin: 0 0 8px 0; font-size: 18px; font-weight: 500; color: #333;}.empty-description { margin: 0; font-size: 14px; color: #999; line-height: 1.6;}</style>
步骤6:修改 App.vue 文件
拷贝以下代码到
src/App.vue 中,即完成了多人音视频房间基础能力。<template><UIKitProvider theme="light" language="zh-CN"><div class="app-container"><header class="app-header"><div class="header-content"><h1 class="app-title">AtomicX Room</h1><LoginUserInfo /></div></header><main class="app-main" v-if="loginUserInfo"><div class="control-panel"><RoomControl /><DeviceControl /></div><RoomMain /></main><div v-else class="welcome-screen"><div class="welcome-content"><h2>欢迎使用 AtomicX Room</h2><p>请先登录以开始使用</p></div></div></div></UIKitProvider></template><script setup>import { UIKitProvider } from '@tencentcloud/uikit-base-component-vue3';import LoginUserInfo from './components/LoginUserInfo.vue';import RoomControl from './components/RoomControl.vue';import DeviceControl from './components/DeviceControl.vue';import RoomMain from './components/RoomMain.vue';import { useLoginState } from 'tuikit-atomicx-vue3';const { loginUserInfo } = useLoginState();</script><style>* { box-sizing: border-box;}html, body { width: 100%; height: 100%; margin: 0; padding: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', sans-serif;}#app { width: 100%; height: 100%; background: #f5f5f5;}.app-container { width: 100%; height: 100%; display: flex; flex-direction: column;}.app-header { background: white; border-bottom: 1px solid #e5e5e5; padding: 16px 24px;}.header-content { max-width: 1400px; margin: 0 auto; display: flex; justify-content: space-between; align-items: center;}.app-title { margin: 0; font-size: 20px; font-weight: 500; color: #333;}.app-main { flex: 1; display: flex; flex-direction: column; padding: 20px; gap: 16px; max-width: 1400px; width: 100%; margin: 0 auto; overflow: hidden;}.control-panel { display: flex; gap: 16px; flex-wrap: wrap;}.welcome-screen { flex: 1; display: flex; align-items: center; justify-content: center;}.welcome-content { text-align: center; color: #666;}.welcome-content h2 { font-size: 24px; margin: 0 0 8px 0; font-weight: 500; color: #333;}.welcome-content p { font-size: 14px; margin: 0;}</style>
步骤7:运行和测试
启动开发服务器。
npm run dev
pnpm run dev
yarn run dev
启动成功后,请在浏览器中打开调试地址(通常为 http://localhost:5173)访问应用。您将看到 Atomicx Room 的示例 Demo。
准备两个测试账号
打开两个浏览器标签页
窗口 A:使用 user_test_A 登录。
窗口 B:使用 user_test_B 登录。

测试流程
在窗口 A 中:输入房间 ID(例如 "test_room_A"),点击创建房间。
在窗口 A 中:点击打开摄像头和打开麦克风。
在窗口 B 中:输入相同的房间 ID("test_room_A"),点击加入房间。
在窗口 B 中:点击打开摄像头和打开麦克风。
验证两个窗口能否看到对方的视频画面并听到声音。

API 文档
State Hook 名称 | 核心作用与场景 | API 文档 |
useLoginState | 登录鉴权。 管理用户登录生命周期和身份信息。 | |
useDeviceState | 设备与网络。 管理麦克风、摄像头、屏幕共享设备,以及网络质量。 | |
useRoomState | 房间管理。 管理实时房间的生命周期(创建、加入、结束)和核心信息。 | |
useRoomParticipantState | 成员管理。 管理房间内所有参会者信息、角色和权限。 | |
useMessageListState | 聊天消息。 管理消息收发和展示。 | |
useMessageInputState | 聊天输入。管理消息的发送 |
下一步
当您完成了基础的多人音视频房间功能后,您可以参考以下功能指南,进一步丰富和扩展您的特色业务能力。
常见问题
Atomicx 在本地开发时使用正常,但部署到线上环境后无法正常采集用户的摄像头或麦克风设备?
原因分析:浏览器出于安全和隐私保护的考虑,对音视频设备(麦克风、摄像头)的采集有着严格限制。只有在安全环境下,采集操作才会被允许。安全环境协议包括:https://、localhost、file:// 等。HTTP 协议被视为不安全,浏览器会默认禁止其访问媒体设备。
解决方案:若您在本地(localhost)测试一切正常,但部署后出现采集失败,请立即检查您的网页是否部署在 HTTP 协议上。您必须使用 HTTPS 协议部署您的网页,并确保具备有效的安全证书。
相关资源:更多关于 URL 域名及协议的限制详情,请参见 URL 域名及协议限制说明。
Atomicx 是否支持使用 iframe 集成?
支持。使用
iframe 集成 Atomicx 时, 需要在 iframe 标签中配置 allow 属性以授予必要的浏览器权限(麦克风、摄像头、屏幕共享、全屏等),示例如下:// 开启麦克风、摄像头、屏幕分享、全屏权限<iframe allow="microphone; camera; display-capture; display; fullscreen;">