需要添加直播接口

This commit is contained in:
cbb
2026-01-12 17:52:15 +08:00
parent 83fec2617c
commit 13af9eb303
281 changed files with 313157 additions and 104 deletions

View File

@@ -0,0 +1,253 @@
/**
* @module AudioEffectState
* @module_description
* 音效设置管理模块
* 核心功能:提供变声、混响、耳返等高级音效功能,支持多种音效效果和实时音效调节。
* 技术特点:基于音频处理算法,支持实时音效处理、低延迟音频传输、音质优化等高级技术。
* 业务价值:为直播平台提供差异化的音效体验,增强用户参与度和直播趣味性。
* 应用场景变声直播、K歌直播、音效娱乐、专业音效等需要音频处理的场景。
*/
import { ref } from "vue";
import {
SetAudioChangerTypeOptions, SetAudioReverbTypeOptions, SetVoiceEarMonitorEnableOptions,
VolumeOptions, AudioChangerTypeParam, AudioReverbTypeParam
} from "@/uni_modules/tuikit-atomic-x";
import { getRTCRoomEngineManager } from "./rtcRoomEngine";
import { callUTSFunction, safeJsonParse } from "../utils/utsUtils";
/**
* 变声器类型映射表
* @internal
*/
const CHANGER_TYPE_MAP: Record<number, AudioChangerTypeParam> = {
0: 'NONE',
1: 'CHILD',
2: 'LITTLE_GIRL',
3: 'MAN',
4: 'HEAVY_METAL',
5: 'COLD',
6: 'FOREIGNER',
7: 'TRAPPED_BEAST',
8: 'FATSO',
9: 'STRONG_CURRENT',
10: 'HEAVY_MACHINERY',
11: 'ETHEREAL',
} as const;
/**
* 混响类型映射表
* @internal
*/
const REVERB_TYPE_MAP: Record<number, AudioReverbTypeParam> = {
0: 'NONE',
1: 'KTV',
2: 'SMALL_ROOM',
3: 'AUDITORIUM',
4: 'DEEP',
5: 'LOUD',
6: 'METALLIC',
7: 'MAGNETIC',
} as const;
/**
* 耳返开关状态
* @type {Ref<boolean>}
* @memberof module:AudioEffectState
* @example
* import { useAudioEffectState } from '@/uni_modules/tuikit-atomic-x/state/AudioEffectState';
* const { isEarMonitorOpened } = useAudioEffectState('your_live_id');
*
* // 监听耳返开关状态变化
* watch(isEarMonitorOpened, (newStatus) => {
* console.log('耳返开关状态:', newStatus);
* });
*
* // 获取当前耳返开关状态
* const isOpen = isEarMonitorOpened.value;
* console.log('当前耳返状态:', isOpen);
*/
const isEarMonitorOpened = ref<boolean>(false);
/**
* 耳返音量大小
* @type {Ref<number>}
* @memberof module:AudioEffectState
* @example
* import { useAudioEffectState } from '@/uni_modules/tuikit-atomic-x/state/AudioEffectState';
* const { earMonitorVolume } = useAudioEffectState('your_live_id');
*
* // 监听耳返音量变化
* watch(earMonitorVolume, (newVolume) => {
* console.log('耳返音量:', newVolume);
* });
*
* // 获取当前耳返音量
* const volume = earMonitorVolume.value;
* console.log('当前耳返音量:', volume);
*/
const earMonitorVolume = ref<number>(0);
/**
* 变声状态
* @type {Ref<AudioChangerTypeParam>}
* @memberof module:AudioEffectState
* @example
* import { useAudioEffectState } from '@/uni_modules/tuikit-atomic-x/state/AudioEffectState';
* const { audioChangerType } = useAudioEffectState('your_live_id');
*
* // 监听变声类型变化
* watch(audioChangerType, (newType) => {
* console.log('变声类型:', newType);
* });
*
* // 获取当前变声类型
* const type = audioChangerType.value;
* console.log('当前变声类型:', type);
*/
const audioChangerType = ref<AudioChangerTypeParam>('NONE');
/**
* 混响状态
* @type {Ref<AudioReverbTypeParam>}
* @memberof module:AudioEffectState
* @example
* import { useAudioEffectState } from '@/uni_modules/tuikit-atomic-x/state/AudioEffectState';
* const { audioReverbType } = useAudioEffectState('your_live_id');
*
* // 监听混响类型变化
* watch(audioReverbType, (newType) => {
* console.log('混响类型:', newType);
* });
*
* // 获取当前混响类型
* const type = audioReverbType.value;
* console.log('当前混响类型:', type);
*/
const audioReverbType = ref<AudioReverbTypeParam>('NONE');
/**
* 设置变声效果
* @param {SetAudioChangerTypeOptions} params - 变声效果参数
* @returns {void}
* @memberof module:AudioEffectState
* @example
* import { useAudioEffectState } from '@/uni_modules/tuikit-atomic-x/state/AudioEffectState';
* const { setAudioChangerType } = useAudioEffectState("your_live_id");
* setAudioChangerType({ changerType: 'MAN' });
*/
function setAudioChangerType(params: SetAudioChangerTypeOptions): void {
callUTSFunction("setAudioChangerType", params);
}
/**
* 设置混响效果
* @param {SetAudioReverbTypeOptions} params - 混响效果参数
* @returns {void}
* @memberof module:AudioEffectState
* @example
* import { useAudioEffectState } from '@/uni_modules/tuikit-atomic-x/state/AudioEffectState';
* const { setAudioReverbType } = useAudioEffectState("your_live_id");
* setAudioReverbType({ reverbType: 'KTV' });
*/
function setAudioReverbType(params: SetAudioReverbTypeOptions): void {
callUTSFunction("setAudioReverbType", params);
}
/**
* 设置耳返开关状态
* @param {SetVoiceEarMonitorEnableOptions} params - 耳返开关参数
* @returns {void}
* @memberof module:AudioEffectState
* @example
* import { useAudioEffectState } from '@/uni_modules/tuikit-atomic-x/state/AudioEffectState';
* const { setVoiceEarMonitorEnable } = useAudioEffectState("your_live_id");
* setVoiceEarMonitorEnable({ enable: true });
*/
function setVoiceEarMonitorEnable(params: SetVoiceEarMonitorEnableOptions): void {
callUTSFunction("setVoiceEarMonitorEnable", params);
}
/**
* 设置耳返音量大小
* @param {VolumeOptions} params - 耳返音量参数
* @returns {void}
* @memberof module:AudioEffectState
* @example
* import { useAudioEffectState } from '@/uni_modules/tuikit-atomic-x/state/AudioEffectState';
* const { setVoiceEarMonitorVolume } = useAudioEffectState("your_live_id");
* setVoiceEarMonitorVolume({ volume: 50 });
*/
function setVoiceEarMonitorVolume(params: VolumeOptions): void {
callUTSFunction("setVoiceEarMonitorVolume", params);
}
const onAudioEffectStoreChanged = (eventName: string, res: string): void => {
try {
if (eventName === "isEarMonitorOpened") {
const data = safeJsonParse<boolean>(res, false);
isEarMonitorOpened.value = data;
} else if (eventName === "earMonitorVolume") {
const data = safeJsonParse<number>(res, 0);
earMonitorVolume.value = data;
} else if (eventName === "audioChangerType") {
const typeCode = safeJsonParse<number>(res, -1);
const type = mapChangerTypeCodeToChangerType(typeCode);
if (type) {
audioChangerType.value = type;
} else {
console.error(`Invalid changer type code received: ${typeCode}`);
}
} else if (eventName === "audioReverbType") {
const typeCode = safeJsonParse<number>(res, -1);
const type = mapReverbTypeCodeToReverbType(typeCode);
if (type) {
audioReverbType.value = type;
} else {
console.error(`Invalid reverb type code received: ${typeCode}`);
}
}
} catch (error) {
console.error("onAudioEffectStoreChanged error:", error);
}
};
function mapChangerTypeCodeToChangerType(typeCode: number): AudioChangerTypeParam | null {
const mappedType = CHANGER_TYPE_MAP[typeCode];
if (mappedType === undefined) {
console.warn(`Unknown changer type code: ${typeCode}`);
return null;
}
return mappedType;
}
function mapReverbTypeCodeToReverbType(typeCode: number): AudioReverbTypeParam | null {
const mappedType = REVERB_TYPE_MAP[typeCode];
if (mappedType === undefined) {
console.warn(`Unknown reverb type code: ${typeCode}`);
return null;
}
return mappedType;
}
function bindEvent(liveID: string): void {
getRTCRoomEngineManager().on("audioEffectStoreChanged", onAudioEffectStoreChanged, liveID);
}
export function useAudioEffectState(liveID: string) {
bindEvent(liveID);
return {
audioChangerType, // 变声状态
audioReverbType, // 混响状态
isEarMonitorOpened, // 耳返开关状态
earMonitorVolume, // 耳返音量大小
setAudioChangerType, // 设置变声效果
setAudioReverbType, // 设置混响效果
setVoiceEarMonitorEnable, // 设置耳返开关
setVoiceEarMonitorVolume, // 设置耳返音量
};
}
export default useAudioEffectState;

View File

@@ -0,0 +1,136 @@
/**
* @module BarrageState
* 弹幕管理管理模块
* @module_description
* 核心功能:处理直播间内的文本消息、自定义消息等弹幕功能,支持弹幕发送、消息状态同步等。
* 技术特点:支持高并发消息处理、实时消息同步、消息过滤、表情包支持等高级功能。
* 业务价值:为直播平台提供核心的互动能力,增强用户参与度和直播氛围。
* 应用场景:弹幕互动、消息管理、表情包、聊天室等社交互动场景。
*/
import { ref } from "vue";
import {
SendTextMessageOptions, SendCustomMessageOptions, BarrageParam, AppendLocalTipOptions
} from "@/uni_modules/tuikit-atomic-x";
import { getRTCRoomEngineManager } from "./rtcRoomEngine";
import { callUTSFunction, safeJsonParse } from "../utils/utsUtils";
/**
* 当前房间的弹幕消息列表
* @type {Ref<BarrageParam[]>}
* @memberof module:BarrageState
* @example
* import { useBarrageState } from '@/uni_modules/tuikit-atomic-x/state/BarrageState';
* const { messageList } = useBarrageState('your_live_id');
*
* // 监听弹幕消息列表变化
* watch(messageList, (newMessages) => {
* if (newMessages && newMessages.length > 0) {
* console.log('弹幕消息列表更新:', newMessages);
* newMessages.forEach(msg => {
* console.log('消息内容:', msg.content);
* console.log('发送者:', msg.sender);
* });
* }
* });
*
* // 获取当前弹幕列表
* const messages = messageList.value;
* console.log('当前弹幕数量:', messages.length);
*/
const messageList = ref<BarrageParam[]>([]);
/**
* 是否允许发送消息
* @type {Ref<boolean>}
* @memberof module:BarrageState
* @example
* import { useBarrageState } from '@/uni_modules/tuikit-atomic-x/state/BarrageState';
* const { allowSendMessage } = useBarrageState('your_live_id');
*
* // 监听消息发送权限变化
* watch(allowSendMessage, (newAllow) => {
* console.log('是否允许发送消息:', newAllow);
* });
*
* // 检查当前是否允许发送消息
* const allowSend = allowSendMessage.value;
* if (allowSend) {
* console.log('已启用消息发送功能');
* }
*/
const allowSendMessage = ref<boolean>(false);
/**
* 发送文本类型弹幕。
* @param {SendTextMessageOptions} params - 发送文本弹幕参数
* @returns {void}
* @memberof module:BarrageState
* @example
* import { useBarrageState } from '@/uni_modules/tuikit-atomic-x/state/BarrageState';
* const { sendTextMessage } = useBarrageState('your_live_id');
* sendTextMessage({ liveID: "your_live_id", text: 'Hello World' });
*/
function sendTextMessage(params : SendTextMessageOptions) : void {
callUTSFunction("sendTextMessage", params);
}
/**
* 添加本地提示消息。
* @param {AppendLocalTipOptions} params - 添加本地提示消息参数
* @returns {void}
* @memberof module:BarrageState
* @example
* import { useBarrageState } from '@/uni_modules/tuikit-atomic-x/state/BarrageState';
* const { appendLocalTip } = useBarrageState('your_live_id');
* appendLocalTip({ liveID: "your_live_id", message: { text: 'Hello World' } });
*/
function appendLocalTip(params : AppendLocalTipOptions) : void {
getRTCRoomEngineManager()["appendLocalTip"](params);
}
/**
* 发送自定义类型弹幕。
* @param {SendCustomMessageOptions} params - 发送自定义类型弹幕参数
* @returns {void}
* @memberof module:BarrageState
* @example
* import { useBarrageState } from '@/uni_modules/tuikit-atomic-x/state/BarrageState';
* const { sendCustomMessage } = useBarrageState('your_live_id');
* sendCustomMessage({ liveID: "your_live_id", businessID: "livekit", data: JSON.stringify("my custom message"});
*/
function sendCustomMessage(params : SendCustomMessageOptions) : void {
callUTSFunction("sendCustomMessage", params);
}
const onBarrageStoreChanged = (eventName : string, res : string) : void => {
try {
if (eventName === "messageList") {
const data = safeJsonParse<BarrageParam[]>(res, []);
messageList.value = data;
} else if (eventName === "allowSendMessage") {
const data = safeJsonParse<boolean>(res, false);
allowSendMessage.value = data;
}
} catch (error) {
console.error("onBarrageStoreChanged JSON parse error:", error);
}
};
function bindEvent(liveID : string) {
getRTCRoomEngineManager().on("barrageStoreChanged", onBarrageStoreChanged, liveID);
}
export function useBarrageState(liveID : string) {
bindEvent(liveID);
return {
messageList, // 当前房间的弹幕消息列表
// allowSendMessage, // 是否允许发送消息 TODO待支持
sendTextMessage, // 发送文本消息方法
sendCustomMessage, // 发送自定义消息方法
appendLocalTip // 添加本地提示消息方法
};
}
export default useBarrageState;

View File

@@ -0,0 +1,173 @@
/**
* @module BaseBeautyState
* @module_description
* 基础美颜管理模块
* 核心功能:提供磨皮、美白、红润等基础美颜效果调节,支持实时美颜参数调整。
* 技术特点:支持实时美颜处理、参数平滑调节、性能优化等高级技术。
* 业务价值:为直播平台提供基础的美颜能力,提升用户形象和直播质量。
* 应用场景:美颜直播、形象优化、美颜调节、直播美化等需要美颜功能的场景。
*/
import { ref } from "vue";
import { SetSmoothLevelOptions, SetWhitenessLevelOptions, SetRuddyLevelOptions } from "@/uni_modules/tuikit-atomic-x";
import { getRTCRoomEngineManager } from "./rtcRoomEngine";
import { callUTSFunction, safeJsonParse } from "../utils/utsUtils";
/**
* 磨皮级别 取值范围[0,9]: 0 表示关闭9 表示效果最明显
* @type {Ref<number>}
* @memberof module:BaseBeautyState
* @example
* import { useBaseBeautyState } from '@/uni_modules/tuikit-atomic-x/state/BaseBeautyState';
* const { smoothLevel } = useBaseBeautyState('your_live_id');
*
* // 监听磨皮级别变化
* watch(smoothLevel, (newLevel) => {
* console.log('磨皮级别:', newLevel);
* });
*
* // 获取当前磨皮级别
* const level = smoothLevel.value;
* console.log('当前磨皮级别:', level);
*/
const smoothLevel = ref<number>(0);
/**
* 美白级别 取值范围[0,9]: 0 表示关闭9 表示效果最明显
* @type {Ref<number>}
* @memberof module:BaseBeautyState
* @example
* import { useBaseBeautyState } from '@/uni_modules/tuikit-atomic-x/state/BaseBeautyState';
* const { whitenessLevel } = useBaseBeautyState('your_live_id');
*
* // 监听美白级别变化
* watch(whitenessLevel, (newLevel) => {
* console.log('美白级别:', newLevel);
* });
*
* // 获取当前美白级别
* const level = whitenessLevel.value;
* console.log('当前美白级别:', level);
*/
const whitenessLevel = ref<number>(0);
/**
* 红润级别 取值范围[0,9]: 0 表示关闭9 表示效果最明显
* @type {Ref<number>}
* @memberof module:BaseBeautyState
* @example
* import { useBaseBeautyState } from '@/uni_modules/tuikit-atomic-x/state/BaseBeautyState';
* const { ruddyLevel } = useBaseBeautyState('your_live_id');
*
* // 监听红润级别变化
* watch(ruddyLevel, (newLevel) => {
* console.log('红润级别:', newLevel);
* });
*
* // 获取当前红润级别
* const level = ruddyLevel.value;
* console.log('当前红润级别:', level);
*/
const ruddyLevel = ref<number>(0);
const realUiValues = ref({
whiteness: 0,
smooth: 0,
ruddy: 0
});
/**
* 设置磨皮级别
* @param {SetSmoothLevelOptions} params - 磨皮参数,取值范围[0,9]: 0 表示关闭9 表示效果最明显
* @returns {void}
* @memberof module:BaseBeautyState
* @example
* import { useBaseBeautyState } from '@/uni_modules/tuikit-atomic-x/state/BaseBeautyState';
* const { setSmoothLevel } = useBaseBeautyState('your_live_id');
* setSmoothLevel({ smoothLevel: 5 });
*/
function setSmoothLevel(params: SetSmoothLevelOptions): void {
callUTSFunction("setSmoothLevel", params);
}
/**
* 设置美白级别
* @param {SetWhitenessLevelOptions} params - 美白参数,取值范围[0,9]: 0 表示关闭9 表示效果最明显
* @returns {void}
* @memberof module:BaseBeautyState
* @example
* import { useBaseBeautyState } from '@/uni_modules/tuikit-atomic-x/state/BaseBeautyState';
* const { setWhitenessLevel } = useBaseBeautyState('your_live_id');
* setWhitenessLevel({ whitenessLevel: 6 });
*/
function setWhitenessLevel(params: SetWhitenessLevelOptions): void {
callUTSFunction("setWhitenessLevel", params);
}
/**
* 设置红润级别
* @param {SetRuddyLevelOptions} params - 红润参数,取值范围[0,9]: 0 表示关闭9 表示效果最明显
* @returns {void}
* @memberof module:BaseBeautyState
* @example
* import { useBaseBeautyState } from '@/uni_modules/tuikit-atomic-x/state/BaseBeautyState';
* const { setRuddyLevel } = useBaseBeautyState('your_live_id');
* setRuddyLevel({ ruddyLevel: 4 });
*/
function setRuddyLevel(params: SetRuddyLevelOptions): void {
callUTSFunction("setRuddyLevel", params);
}
function setRealUiValue(type: 'whiteness' | 'smooth' | 'ruddy', value: number): void {
realUiValues.value[type] = value;
}
function getRealUiValue(type: 'whiteness' | 'smooth' | 'ruddy'): number {
return realUiValues.value[type];
}
function resetRealUiValues(): void {
realUiValues.value.whiteness = 0;
realUiValues.value.smooth = 0;
realUiValues.value.ruddy = 0;
}
const onBeautyStoreChanged = (eventName: string, res: string): void => {
try {
if (eventName === "smoothLevel") {
const data = safeJsonParse<number>(res, 0);
smoothLevel.value = data;
} else if (eventName === "whitenessLevel") {
const data = safeJsonParse<number>(res, 0);
whitenessLevel.value = data;
} else if (eventName === "ruddyLevel") {
const data = safeJsonParse<number>(res, 0);
ruddyLevel.value = data;
}
} catch (error) {
console.error("onBeautyStoreChanged error:", error);
}
};
function bindEvent(liveID: string): void {
getRTCRoomEngineManager().on("beautyStoreChanged", onBeautyStoreChanged, liveID);
}
export function useBaseBeautyState(liveID: string) {
bindEvent(liveID);
return {
smoothLevel, // 磨皮级别状态
whitenessLevel, // 美白级别状态
ruddyLevel, // 红润级别状态
setSmoothLevel, // 设置磨皮级别方法
setWhitenessLevel, // 设置美白级别方法
setRuddyLevel, // 设置红润级别方法
realUiValues,
setRealUiValue,
getRealUiValue,
resetRealUiValues,
};
}
export default useBaseBeautyState;

View File

@@ -0,0 +1,274 @@
/**
* @module BattleState
* @module_description
* 直播 PK 管理模块
* 核心功能处理主播间的PK对战流程包括PK请求、接受、拒绝、退出等完整的PK管理功能。
* 技术特点支持实时PK状态同步、分数统计、PK时长控制、结果计算等高级功能。
* 业务价值:为直播平台提供丰富的互动玩法,增加主播收益和用户粘性。
* 应用场景主播PK、对战直播、分数统计、互动游戏等娱乐互动场景。
*/
import { ref } from "vue";
import { ILiveListener, RequestBattleOptions, CancelBattleRequestOptions, AcceptBattleOptions, RejectBattleOptions, ExitBattleOptions, BattleInfoParam, SeatUserInfoParam } from "@/uni_modules/tuikit-atomic-x";
import { getRTCRoomEngineManager } from "./rtcRoomEngine";
import { callUTSFunction, safeJsonParse } from "../utils/utsUtils";
/**
* 当前 PK 信息
* @type {Ref<BattleInfoParam | null>}
* @memberof module:BattleState
* @example
* import { useBattleState } from '@/uni_modules/tuikit-atomic-x/state/BattleState';
* const { currentBattleInfo } = useBattleState('your_live_id');
*
* // 监听当前 PK 信息变化
* watch(currentBattleInfo, (newBattle) => {
* if (newBattle) {
* console.log(' PK 已开始:', newBattle.battleID);
* }
* });
*
* // 获取当前 PK 信息
* const battle = currentBattleInfo.value;
*/
const currentBattleInfo = ref<BattleInfoParam | null>(null);
/**
* PK 用户列表
* @type {Ref<SeatUserInfoParam[]>}
* @memberof module:BattleState
* @example
* import { useBattleState } from '@/uni_modules/tuikit-atomic-x/state/BattleState';
* const { battleUsers } = useBattleState('your_live_id');
*
* // 监听当前 PK 用户列表变化
* watch(battleUsers, (newUsers) => {
* console.log('PK 用户列表更新:', newUsers);
* });
*
* // 获取当前 PK 用户列表
* const users = battleUsers.value;
* console.log('PK 用户列表更新:', users);
*/
const battleUsers = ref<SeatUserInfoParam[]>([]);
/**
* PK 分数映射
* @type {Ref<Map<string, number>> | null}
* @memberof module:BattleState
* @example
* import { useBattleState } from '@/uni_modules/tuikit-atomic-x/state/BattleState';
* const { battleScore } = useBattleState('your_live_id');
*
* // 监听当前 PK 分数变化
* watch(battleScore, (newScore) => {
* console.log('PK 分数更新:', newScore);
* });
*
* // 获取当前 PK 分数
* const score = battleScore.value;
* console.log('当前 PK 分数:', score);
*/
const battleScore = ref<Map<string, number> | null>(null);
/**
* 请求 PK
* @param {RequestBattleOptions} params - 请求 PK 参数
* @returns {void}
* @memberof module:BattleState
* @example
* import { useBattleState } from '@/uni_modules/tuikit-atomic-x/state/BattleState';
* const { requestBattle } = useBattleState("your_live_id");
* requestBattle({
* liveID: "your_live_id",
* userIDList: ["target_user_id"],
* timeout: 10,
* config: {
* duration: 300,
* needResponse: true,
* extensionInfo: "{"\"type\":\"standard\""}"
* },
* success: (battleInfo, result) => {
* console.log(' PK 请求成功:', battleInfo, result);
* },
* fail: (code, desc) => {
* console.error(' PK 请求失败:', code, desc);
* }
* });
*/
function requestBattle(params : RequestBattleOptions) : void {
callUTSFunction("requestBattle", params);
}
/**
* 取消 PK 请求
* @param {CancelBattleRequestOptions} params - 取消 PK 请求参数
* @returns {void}
* @memberof module:BattleState
* @example
* import { useBattleState } from '@/uni_modules/tuikit-atomic-x/state/BattleState';
* const { cancelBattleRequest } = useBattleState("your_live_id");
* cancelBattleRequest({
* liveID: "your_live_id",
* battleID: "battle_id",
* userIDList: ["target_user_id"],
* success: () => {
* console.log('取消 PK 请求成功');
* },
* fail: (code, desc) => {
* console.error('取消 PK 请求失败:', code, desc);
* }
* });
*/
function cancelBattleRequest(params : CancelBattleRequestOptions) : void {
callUTSFunction("cancelBattleRequest", params);
}
/**
* 接受 PK
* @param {AcceptBattleOptions} params - 接受 PK 参数
* @returns {void}
* @memberof module:BattleState
* @example
* import { useBattleState } from '@/uni_modules/tuikit-atomic-x/state/BattleState';
* const { acceptBattle } = useBattleState("your_live_id");
* acceptBattle({
* liveID: "your_live_id",
* battleID: "battle_id",
* success: () => {
* console.log('接受 PK 成功');
* },
* fail: (code, desc) => {
* console.error('接受 PK 失败:', code, desc);
* }
* });
*/
function acceptBattle(params : AcceptBattleOptions) : void {
callUTSFunction("acceptBattle", params);
}
/**
* 拒绝 PK
* @param {RejectBattleOptions} params - 拒绝 PK 参数
* @returns {void}
* @memberof module:BattleState
* @example
* import { useBattleState } from '@/uni_modules/tuikit-atomic-x/state/BattleState';
* const { rejectBattle } = useBattleState("your_live_id");
* rejectBattle({
* liveID: "your_live_id",
* battleID: "battle_id",
* success: () => {
* console.log('拒绝 PK 成功');
* },
* fail: (code, desc) => {
* console.error('拒绝 PK 失败:', code, desc);
* }
* });
*/
function rejectBattle(params : RejectBattleOptions) : void {
callUTSFunction("rejectBattle", params);
}
/**
* 退出 PK
* @param {ExitBattleOptions} params - 退出 PK 参数
* @returns {void}
* @memberof module:BattleState
* @example
* import { useBattleState } from '@/uni_modules/tuikit-atomic-x/state/BattleState';
* const { exitBattle } = useBattleState("your_live_id");
* exitBattle({
* liveID: "your_live_id",
* battleID: "battle_id",
* success: () => {
* console.log('退出 PK 成功');
* },
* fail: (code, desc) => {
* console.error('退出 PK 失败:', code, desc);
* }
* });
*/
function exitBattle(params : ExitBattleOptions) : void {
callUTSFunction("exitBattle", params);
}
/**
* 添加 PK 事件监听器
* @param {string} liveID - 直播间ID
* @param {string} eventName - 事件名称,可选值: 'onBattleStarted'( PK 开始)<br>'onBattleEnded'( PK 结束)<br>'onUserJoinBattle'(当前有用户加入 PK 对战)<br>'onUserExitBattle'(当前有用户退出 PK 对战)<br>'onBattleRequestReceived'(收到 PK 请求)<br>'onBattleRequestCancelled'(取消 PK 请求)<br>'onBattleRequestTimeout'(当前 PK 对战请求超时)<br>'onBattleRequestAccept'(当前 PK 对战请求被接受)<br>'onBattleRequestReject'(当前 PK 对战请求被拒绝)
* @param {ILiveListener} listener - 事件处理函数
* @returns {void}
* @memberof module:BattleState
* @example
* import { useBattleState } from '@/uni_modules/tuikit-atomic-x/state/BattleState';
* const { addBattleListener } = useBattleState('your_live_id');
* addBattleListener('your_live_id', 'onBattleStarted', {
* callback: (params) => {
* console.log(' PK 已开始:', params);
* }
* });
*/
function addBattleListener(liveID : string, eventName : string, listener : ILiveListener) : void {
getRTCRoomEngineManager().addBattleListener(liveID, eventName, listener);
}
/**
* 移除 PK 事件监听器
* @param {string} liveID - 直播间ID
* @param {string} eventName - 事件名称,可选值: 'onBattleStarted'( PK 开始)<br>'onBattleEnded'( PK 结束)<br>'onUserJoinBattle'(当前有用户加入 PK 对战)<br>'onUserExitBattle'(当前有用户退出 PK 对战)<br>'onBattleRequestReceived'(收到 PK 请求)<br>'onBattleRequestCancelled'(取消 PK 请求)<br>'onBattleRequestTimeout'(当前 PK 对战请求超时)<br>'onBattleRequestAccept'(当前 PK 对战请求被接受)<br>'onBattleRequestReject'(当前 PK 对战请求被拒绝)
* @param {ILiveListener} listener - 事件处理函数
* @returns {void}
* @memberof module:BattleState
* @example
* import { useBattleState } from '@/uni_modules/tuikit-atomic-x/state/BattleState';
* const { removeBattleListener } = useBattleState('your_live_id');
* removeBattleListener('your_live_id', 'onBattleStarted', battleListener);
*/
function removeBattleListener(liveID : string, eventName : string, listener : ILiveListener) : void {
getRTCRoomEngineManager().removeBattleListener(liveID, eventName, listener);
}
const onBattleStoreChanged = (eventName : string, res : string) : void => {
try {
switch (eventName) {
case "currentBattleInfo":
const battleData = safeJsonParse<BattleInfoParam | null>(res, null);
currentBattleInfo.value = battleData;
break;
case "battleUsers":
const requestsData = safeJsonParse<SeatUserInfoParam[]>(res, []);
battleUsers.value = requestsData;
break;
case "battleScore":
const scoreData = safeJsonParse<Map<string, number> | null>(res, null);
battleScore.value = scoreData;
break;
}
} catch (error) {
console.error("onBattleStoreChanged JSON parse error:", error);
}
};
function bindEvent(liveID : string) : void {
getRTCRoomEngineManager().on("battleStoreChanged", onBattleStoreChanged, liveID);
}
export function useBattleState(liveID : string) {
bindEvent(liveID);
return {
currentBattleInfo, // 当前 PK 信息
battleUsers, // PK 用户列表
battleScore, // PK 分数映射
requestBattle, // 请求 PK
cancelBattleRequest, // 取消 PK 请求
acceptBattle, // 接受 PK
rejectBattle, // 拒绝 PK
exitBattle, // 退出 PK
addBattleListener, // 添加 PK 事件监听
removeBattleListener // 移除 PK 事件监听
};
}
export default useBattleState;

View File

@@ -0,0 +1,367 @@
/**
* @module CoGuestState
* @module_description
* 直播连麦管理相关接口
* 核心功能:处理观众与主播之间的连麦互动,管理连麦申请、邀请、接受、拒绝等完整的连麦流程。
* 技术特点:基于音视频技术,支持连麦状态实时同步、音视频质量自适应、网络状况监控等高级功能。
* 业务价值:为直播平台提供观众参与互动的核心能力,增强用户粘性和直播趣味性。
* 应用场景观众连麦、互动问答、在线K歌、游戏直播等需要观众参与的互动场景。
*/
import { ref } from "vue";
import {
ApplyForSeatOptions, CancelApplicationOptions, AcceptApplicationOptions, RejectApplicationOptions,
InviteToSeatOptions, CancelInvitationOptions, AcceptInvitationOptions, RejectInvitationOptions, DisconnectOptions,
LiveUserInfoParam, SeatUserInfoParam, ILiveListener,
} from "@/uni_modules/tuikit-atomic-x";
import { getRTCRoomEngineManager } from "./rtcRoomEngine";
import { callUTSFunction, safeJsonParse } from "../utils/utsUtils";
/**
* 已连接的连麦嘉宾列表
* @type {Ref<SeatUserInfoParam[]>}
* @memberof module:CoGuestState
* @example
* import { useCoGuestState } from '@/uni_modules/tuikit-atomic-x/state/CoGuestState';
* const { connected } = useCoGuestState('your_live_id');
*
* // 监听已连接的连麦嘉宾列表变化
* watch(connected, (newConnected) => {
* if (newConnected && newConnected.length > 0) {
* console.log('连麦嘉宾列表更新:', newConnected);
* newConnected.forEach(guest => {
* console.log('嘉宾用户ID:', guest.userID);
* console.log('嘉宾昵称:', guest.nickname);
* });
* }
* });
*
* // 获取当前连麦嘉宾列表
* const guests = connected.value;
* console.log('当前连麦嘉宾数量:', guests.length);
*/
const connected = ref<SeatUserInfoParam[]>([]);
/**
* 被邀请上麦的用户列表
* @type {Ref<LiveUserInfoParam[]>}
* @memberof module:CoGuestState
* @example
* import { useCoGuestState } from '@/uni_modules/tuikit-atomic-x/state/CoGuestState';
* const { invitees } = useCoGuestState('your_live_id');
*
* // 监听被邀请用户列表变化
* watch(invitees, (newInvitees) => {
* if (newInvitees && newInvitees.length > 0) {
* console.log('被邀请用户列表更新:', newInvitees);
* newInvitees.forEach(user => {
* console.log('被邀请用户ID:', user.userID);
* console.log('被邀请用户昵称:', user.nickname);
* });
* }
* });
*
* // 获取当前被邀请用户列表
* const invitedUsers = invitees.value;
* console.log('当前被邀请用户数量:', invitedUsers.length);
*/
const invitees = ref<LiveUserInfoParam[]>([]);
/**
* 申请上麦的用户列表
* @type {Ref<LiveUserInfoParam[]>}
* @memberof module:CoGuestState
* @example
* import { useCoGuestState } from '@/uni_modules/tuikit-atomic-x/state/CoGuestState';
* const { applicants } = useCoGuestState('your_live_id');
*
* // 监听申请上麦用户列表变化
* watch(applicants, (newApplicants) => {
* if (newApplicants && newApplicants.length > 0) {
* console.log('申请上麦用户列表更新:', newApplicants);
* newApplicants.forEach(user => {
* console.log('申请用户ID:', user.userID);
* console.log('申请用户昵称:', user.nickname);
* });
* }
* });
*
* // 获取当前申请上麦用户列表
* const applyingUsers = applicants.value;
* console.log('当前申请用户数量:', applyingUsers.length);
*/
const applicants = ref<LiveUserInfoParam[]>([]);
/**
* 可邀请上麦的候选用户列表
* @type {Ref<LiveUserInfoParam[]>}
* @memberof module:CoGuestState
* @example
* import { useCoGuestState } from '@/uni_modules/tuikit-atomic-x/state/CoGuestState';
* const { candidates } = useCoGuestState('your_live_id');
*
* // 监听候选用户列表变化
* watch(candidates, (newCandidates) => {
* if (newCandidates && newCandidates.length > 0) {
* console.log('候选用户列表更新:', newCandidates);
* newCandidates.forEach(user => {
* console.log('候选用户ID:', user.userID);
* console.log('候选用户昵称:', user.nickname);
* });
* }
* });
*
* // 获取当前候选用户列表
* const candidateUsers = candidates.value;
* console.log('当前候选用户数量:', candidateUsers.length);
*/
const candidates = ref<LiveUserInfoParam[]>([]);
/**
* 申请连麦座位
* @param {ApplyForSeatOptions} params - 申请连麦座位参数
* @returns {void}
* @memberof module:CoGuestState
* @example
* import { useCoGuestState } from '@/uni_modules/tuikit-atomic-x/state/CoGuestState';
* const { applyForSeat } = useCoGuestState("your_live_id");
* applyForSeat({ seatIndex: 2, timeout: 10 , extension: 'extra info'});
*/
function applyForSeat(params: ApplyForSeatOptions): void {
callUTSFunction("applyForSeat", params);
}
/**
* 取消申请
* @param {CancelApplicationOptions} params - 取消申请参数
* @returns {void}
* @memberof module:CoGuestState
* @example
* import { useCoGuestState } from '@/uni_modules/tuikit-atomic-x/state/CoGuestState';
* const { cancelApplication } = useCoGuestState("your_live_id");
* cancelApplication({});
*/
function cancelApplication(params: CancelApplicationOptions): void {
callUTSFunction("cancelApplication", params);
}
/**
* 接受申请
* @param {AcceptApplicationOptions} params - 接受申请参数
* @returns {void}
* @memberof module:CoGuestState
* @example
* import { useCoGuestState } from '@/uni_modules/tuikit-atomic-x/state/CoGuestState';
* const { acceptApplication } = useCoGuestState("your_live_id");
* acceptApplication({ userID: 'user123', seatIndex: 0 });
*/
function acceptApplication(params: AcceptApplicationOptions): void {
callUTSFunction("acceptApplication", params);
}
/**
* 拒绝申请
* @param {RejectApplicationOptions} params - 拒绝申请参数
* @returns {void}
* @memberof module:CoGuestState
* @example
* import { useCoGuestState } from '@/uni_modules/tuikit-atomic-x/state/CoGuestState';
* const { rejectApplication } = useCoGuestState("your_live_id");
* rejectApplication({ userID: 'user123' });
*/
function rejectApplication(params: RejectApplicationOptions): void {
callUTSFunction("rejectApplication", params);
}
/**
* 邀请上麦
* @param {InviteToSeatOptions} params - 邀请上麦参数
* @returns {void}
* @memberof module:CoGuestState
* @example
* import { useCoGuestState } from '@/uni_modules/tuikit-atomic-x/state/CoGuestState';
* const { inviteToSeat } = useCoGuestState("your_live_id");
* inviteToSeat({ userID: 'user123', seatIndex: 2, timeout: 10 , extension: 'extra info'});
*/
function inviteToSeat(params: InviteToSeatOptions): void {
callUTSFunction("inviteToSeat", params);
}
/**
* 取消邀请
* @param {CancelInvitationOptions} params - 取消邀请参数
* @returns {void}
* @memberof module:CoGuestState
* @example
* import { useCoGuestState } from '@/uni_modules/tuikit-atomic-x/state/CoGuestState';
* const { cancelInvitation } = useCoGuestState("your_live_id");
* cancelInvitation({ inviteeID: 'user123' });
*/
function cancelInvitation(params: CancelInvitationOptions): void {
callUTSFunction("cancelInvitation", params);
}
/**
* 接受邀请
* @param {AcceptInvitationOptions} params - 接受邀请参数
* @returns {void}
* @memberof module:CoGuestState
* @example
* import { useCoGuestState } from '@/uni_modules/tuikit-atomic-x/state/CoGuestState';
* const { acceptInvitation } = useCoGuestState("your_live_id");
* acceptInvitation({ inviterID: 'user123' });
*/
function acceptInvitation(params: AcceptInvitationOptions): void {
callUTSFunction("acceptInvitation", params);
}
/**
* 拒绝邀请
* @param {RejectInvitationOptions} params - 拒绝邀请参数
* @returns {void}
* @memberof module:CoGuestState
* @example
* import { useCoGuestState } from '@/uni_modules/tuikit-atomic-x/state/CoGuestState';
* const { rejectInvitation } = useCoGuestState("your_live_id");
* rejectInvitation({ inviterID: 'user123'});
*/
function rejectInvitation(params: RejectInvitationOptions): void {
callUTSFunction("rejectInvitation", params);
}
/**
* 断开连麦连接
* @param {DisconnectOptions} params - 断开连接参数
* @returns {void}
* @memberof module:CoGuestState
* @example
* import { useCoGuestState } from '@/uni_modules/tuikit-atomic-x/state/CoGuestState';
* const { disconnect } = useCoGuestState("your_live_id");
* disconnect();
*/
function disconnect(params: DisconnectOptions): void {
callUTSFunction("disconnect", params);
}
/**
* 添加连麦嘉宾侧事件监听
* @param {string} liveID - 直播间ID
* @param {string} eventName - 事件名称,可选值: 'onHostInvitationReceived'(收到主播邀请)<br>'onHostInvitationCancelled'(主播取消邀请)<br>'onGuestApplicationResponded'(嘉宾申请响应)<br>'onGuestApplicationNoResponse'(嘉宾申请无响应)<br>'onKickedOffSeat'(被踢下座位)
* @param {ILiveListener} listener - 事件回调函数
* @returns {void}
* @memberof module:CoGuestState
* @example
* import { useCoGuestState } from '@/uni_modules/tuikit-atomic-x/state/CoGuestState';
* const { addCoGuestGuestListener } = useCoGuestState("your_live_id");
* addCoGuestGuestListener('your_live_id', 'onHostInvitationReceived', {
* callback: (params) => {
* console.log('result:', params);
* }
* });
*/
function addCoGuestGuestListener(liveID: string, eventName: string, listener: ILiveListener): void {
getRTCRoomEngineManager().addCoGuestGuestListener(liveID, eventName, listener);
}
/**
* 移除连麦嘉宾侧事件监听
* @param {string} liveID - 直播间ID
* @param {string} eventName - 事件名称,可选值: 'onHostInvitationReceived'(收到主播邀请)<br>'onHostInvitationCancelled'(主播取消邀请)<br>'onGuestApplicationResponded'(嘉宾申请响应)<br>'onGuestApplicationNoResponse'(嘉宾申请无响应)<br>'onKickedOffSeat'(被踢下座位)
* @param {ILiveListener} listener - 事件回调函数
* @returns {void}
* @memberof module:CoGuestState
* @example
* import { useCoGuestState } from '@/uni_modules/tuikit-atomic-x/state/CoGuestState';
* const { removeCoGuestGuestListener } = useCoGuestState("your_live_id");
* removeCoGuestGuestListener('your_live_id', 'onHostInvitationReceived', guestListener);
*/
function removeCoGuestGuestListener(liveID: string, eventName: string, listener: ILiveListener): void {
getRTCRoomEngineManager().removeCoGuestGuestListener(liveID, eventName, listener);
}
/**
* 添加连麦主播侧事件监听
* @param {string} liveID - 直播间ID
* @param {string} eventName - 事件名称,可选值: 'onGuestApplicationReceived'(收到嘉宾申请)<br>'onGuestApplicationCancelled'(嘉宾取消申请)<br>'onGuestApplicationProcessedByOtherHost'(嘉宾申请被其他主播处理)<br>'onHostInvitationResponded'(主播邀请得到回应)<br>'onHostInvitationNoResponse'(主播邀请无响应)
* @param {ILiveListener} listener - 事件回调函数
* @returns {void}
* @memberof module:CoGuestState
* @example
* import { useCoGuestState } from '@/uni_modules/tuikit-atomic-x/state/CoGuestState';
* const { addCoGuestHostListener } = useCoGuestState("your_live_id");
* addCoGuestHostListener('your_live_id', 'onGuestApplicationReceived', {
* callback: (params) => {
* console.log('result:', params);
* }
* });
*/
function addCoGuestHostListener(liveID: string, eventName: string, listener: ILiveListener): void {
getRTCRoomEngineManager().addCoGuestHostListener(liveID, eventName, listener);
}
/**
* 移除连麦主播侧事件监听
* @param {string} liveID - 直播间ID
* @param {string} eventName - 事件名称,可选值: 'onGuestApplicationReceived'(收到嘉宾申请)<br>'onGuestApplicationCancelled'(嘉宾取消申请)<br>'onGuestApplicationProcessedByOtherHost'(嘉宾申请被其他主播处理)<br>'onHostInvitationResponded'(主播邀请得到回应)<br>'onHostInvitationNoResponse'(主播邀请无响应)
* @param {ILiveListener} listener - 事件回调函数
* @returns {void}
* @memberof module:CoGuestState
* @example
* import { useCoGuestState } from '@/uni_modules/tuikit-atomic-x/state/CoGuestState';
* const { removeCoGuestHostListener } = useCoGuestState("your_live_id");
* removeCoGuestHostListener('your_live_id', 'onGuestApplicationReceived', hostListener);
*/
function removeCoGuestHostListener(liveID: string, eventName: string, listener: ILiveListener): void {
getRTCRoomEngineManager().removeCoGuestHostListener(liveID, eventName, listener);
}
const onCoGuestStoreChanged = (eventName: string, res: string): void => {
try {
if (eventName === "connected") {
const data = safeJsonParse<SeatUserInfoParam[]>(res, []);
connected.value = data;
} else if (eventName === "invitees") {
const data = safeJsonParse<LiveUserInfoParam[]>(res, []);
invitees.value = data;
} else if (eventName === "applicants") {
const data = safeJsonParse<LiveUserInfoParam[]>(res, []);
applicants.value = data;
} else if (eventName === "candidates") {
const data = safeJsonParse<LiveUserInfoParam[]>(res, []);
candidates.value = data;
}
} catch (error) {
console.error("onCoGuestStoreChanged error:", error);
}
};
function bindEvent(liveID: string): void {
getRTCRoomEngineManager().on("coGuestStoreChanged", onCoGuestStoreChanged, liveID);
}
export function useCoGuestState(liveID: string) {
bindEvent(liveID);
return {
connected, // 已连接的连麦嘉宾列表
invitees, // 被邀请上麦的用户列表
applicants, // 申请上麦的用户列表
candidates, // 可邀请上麦的候选用户列表
applyForSeat, // 申请连麦座位
cancelApplication, // 取消申请
acceptApplication, // 接受申请
rejectApplication, // 拒绝申请
inviteToSeat, // 邀请上麦
cancelInvitation, // 取消邀请
acceptInvitation, // 接受邀请
rejectInvitation, // 拒绝邀请
disconnect, // 断开连麦连接
addCoGuestGuestListener, // 添加嘉宾侧事件监听
removeCoGuestGuestListener,// 移除嘉宾侧事件监听
addCoGuestHostListener, // 添加主播侧事件监听
removeCoGuestHostListener, // 移除主播侧事件监听
};
}
export default useCoGuestState;

View File

@@ -0,0 +1,277 @@
/**
* @module CoHostState
* @module_description
* 连线主播管理模块
* 核心功能:实现主播间的连线功能,支持主播邀请、连线申请、连线状态管理等主播间互动功能。
* 技术特点:支持多主播音视频同步、画中画显示、音视频质量优化等高级技术,确保连线体验的流畅性。
* 业务价值为直播平台提供主播间协作的核心能力支持PK、合作直播等高级业务场景。
* 应用场景:主播连线、合作直播、跨平台连线、主播互动等高级直播场景。
*/
import { ref } from "vue";
import {
LiveUserInfoParam,
RequestHostConnectionOptions, CancelHostConnectionOptions, AcceptHostConnectionOptions,
RejectHostConnectionOptions, ExitHostConnectionOptions, ILiveListener
} from "@/uni_modules/tuikit-atomic-x";
import { getRTCRoomEngineManager } from "./rtcRoomEngine";
import { callUTSFunction, safeJsonParse } from "../utils/utsUtils";
/**
* 已连接的连线主播列表
* @type {Ref<LiveUserInfoParam[]>}
* @memberof module:CoHostState
* @example
* import { useCoHostState } from '@/uni_modules/tuikit-atomic-x/state/CoHostState';
* const { connected } = useCoHostState('your_live_id');
*
* // 监听已连接的连线主播列表变化
* watch(connected, (newConnected) => {
* if (newConnected && newConnected.length > 0) {
* console.log('已连接的主播列表:', newConnected);
* }
* });
*
* // 获取当前已连接的连线主播数量
* const coHosts = connected.value;
* console.log('已连接的主播数:', coHosts.length);
*/
const connected = ref<LiveUserInfoParam[]>([]);
/**
* 被邀请连线的主播列表
* @type {Ref<LiveUserInfoParam[]>}
* @memberof module:CoHostState
* @example
* import { useCoHostState } from '@/uni_modules/tuikit-atomic-x/state/CoHostState';
* const { invitees } = useCoHostState('your_live_id');
*
* // 监听被邀请的主播列表变化
* watch(invitees, (newInvitees) => {
* if (newInvitees && newInvitees.length > 0) {
* console.log('被邀请的主播列表:', newInvitees);
* }
* });
*
* // 获取当前被邀请的主播列表
* const invitedHosts = invitees.value;
* console.log('被邀请的主播数:', invitedHosts.length);
*/
const invitees = ref<LiveUserInfoParam[]>([]);
/**
* 当前申请连线的主播信息
* @type {Ref<LiveUserInfoParam | undefined>}
* @memberof module:CoHostState
* @example
* import { useCoHostState } from '@/uni_modules/tuikit-atomic-x/state/CoHostState';
* const { applicant } = useCoHostState('your_live_id');
*
* // 监听申请连线的主播信息变化
* watch(applicant, (newApplicant) => {
* if (newApplicant) {
* console.log('申请主播:', newApplicant.userID);
* }
* });
*
* // 获取当前申请连线的主播信息
* const currentApplicant = applicant.value;
* if (currentApplicant) {
* console.log('当前申请连线的主播:', currentApplicant.nickname);
* }
*/
const applicant = ref<LiveUserInfoParam | undefined>();
/**
* 可邀请连线的候选主播列表
* @type {Ref<LiveUserInfoParam[]>}
* @memberof module:CoHostState
* @example
* import { useCoHostState } from '@/uni_modules/tuikit-atomic-x/state/CoHostState';
* const { candidates } = useCoHostState('your_live_id');
*
* // 监听候选主播列表变化
* watch(candidates, (newCandidates) => {
* if (newCandidates && newCandidates.length > 0) {
* console.log('候选主播列表:', newCandidates);
* }
* });
*
* // 获取当前候选主播列表
* const candidateHosts = candidates.value;
* console.log('候选主播数:', candidateHosts.length);
*/
const candidates = ref<LiveUserInfoParam[]>([]);
/**
* 当前连线状态
* @type {Ref<string>}
* @memberof module:CoHostState
* @example
* import { useCoHostState } from '@/uni_modules/tuikit-atomic-x/state/CoHostState';
* const { coHostStatus } = useCoHostState('your_live_id');
*
* // 监听连线状态变化
* watch(coHostStatus, (newStatus) => {
* console.log('连线状态:', newStatus);
* });
*
* // 获取当前连线状态
* const status = coHostStatus.value;
* console.log('当前连线状态:', status);
*/
const coHostStatus = ref<string>('')
/**
* 请求连线
* @param {RequestHostConnectionOptions} params - 请求连线参数
* @returns {void}
* @memberof module:CoHostState
* @example
* import { useCoHostState } from '@/uni_modules/tuikit-atomic-x/state/CoHostState';
* const { requestHostConnection } = useCoHostState("your_live_id");
* requestHostConnection({});
*/
function requestHostConnection(params: RequestHostConnectionOptions): void {
callUTSFunction("requestHostConnection", params);
}
/**
* 取消连线请求
* @param {CancelHostConnectionOptions} params - 取消连线请求参数
* @returns {void}
* @memberof module:CoHostState
* @example
* import { useCoHostState } from '@/uni_modules/tuikit-atomic-x/state/CoHostState';
* const { cancelHostConnection } = useCoHostState(“your_live_id”);
* cancelHostConnection({ toHostLiveID : "target_live_id" });
*/
function cancelHostConnection(params: CancelHostConnectionOptions): void {
callUTSFunction("cancelHostConnection", params);
}
/**
* 接受连线请求
* @param {AcceptHostConnectionOptions} params - 接受连线请求参数
* @returns {void}
* @memberof module:CoHostState
* @example
* import { useCoHostState } from '@/uni_modules/tuikit-atomic-x/state/CoHostState';
* const { acceptHostConnection } = useCoHostState(“your_live_id”);
* acceptHostConnection({ fromHostLiveID: "from_live_id" });
*/
function acceptHostConnection(params: AcceptHostConnectionOptions): void {
callUTSFunction("acceptHostConnection", params);
}
/**
* 拒绝连线请求
* @param {RejectHostConnectionOptions} params - 拒绝连线请求参数
* @returns {void}
* @memberof module:CoHostState
* @example
* import { useCoHostState } from '@/uni_modules/tuikit-atomic-x/state/CoHostState';
* const { rejectHostConnection } = useCoHostState(“your_live_id”);
* rejectHostConnection({ fromHostLiveID: "from_live_id" });
*/
function rejectHostConnection(params: RejectHostConnectionOptions): void {
callUTSFunction("rejectHostConnection", params);
}
/**
* 退出连线
* @param {ExitHostConnectionOptions} params - 退出连线参数
* @returns {void}
* @memberof module:CoHostState
* @example
* import { useCoHostState } from '@/uni_modules/tuikit-atomic-x/state/CoHostState';
* const { exitHostConnection } = useCoHostState(“your_live_id”);
* exitHostConnection({});
*/
function exitHostConnection(params: ExitHostConnectionOptions): void {
callUTSFunction("exitHostConnection", params);
}
/**
* 添加连线主播事件监听
* @param {string} liveID - 直播间ID
* @param {string} eventName - 事件名称,可选值: 'onCoHostRequestReceived'(收到连线请求)<br>'onCoHostRequestCancelled'(连线请求被取消)<br>'onCoHostRequestAccepted'(连线请求被接受)<br>'onCoHostRequestRejected'(连线请求被拒绝)<br>'onCoHostRequestTimeout'(连线请求超时)<br>'onCoHostUserJoined'(连线用户加入)<br>'onCoHostUserLeft'(连线用户离开)
* @param {ILiveListener} listener - 事件回调函数
* @returns {void}
* @memberof module:CoHostState
* @example
* import { useCoHostState } from '@/uni_modules/tuikit-atomic-x/state/CoHostState';
* const { addCoHostListener } = useCoHostState("your_live_id");
* addCoHostListener('your_live_id', 'onCoHostRequestReceived', {
* callback: (params) => {
* console.log('result:', params);
* }
* });
*/
function addCoHostListener(liveID: string, eventName: string, listener: ILiveListener): void {
getRTCRoomEngineManager().addCoHostListener(liveID, eventName, listener);
}
/**
* 移除连线主播事件监听
* @param {string} liveID - 直播间ID
* @param {string} eventName - 事件名称,可选值: 'onCoHostRequestReceived'(收到连线请求)<br>'onCoHostRequestCancelled'(连线请求被取消)<br>'onCoHostRequestAccepted'(连线请求被接受)<br>'onCoHostRequestRejected'(连线请求被拒绝)<br>'onCoHostRequestTimeout'(连线请求超时)<br>'onCoHostUserJoined'(连线用户加入)<br>'onCoHostUserLeft'(连线用户离开)
* @param {ILiveListener} listener - 事件回调函数
* @returns {void}
* @memberof module:CoHostState
* @example
* import { useCoHostState } from '@/uni_modules/tuikit-atomic-x/state/CoHostState';
* const { removeCoHostListener } = useCoHostState("your_live_id");
* removeCoHostListener('your_live_id', 'onCoHostRequestReceived', hostListener);
*/
function removeCoHostListener(liveID: string, eventName: string, listener: ILiveListener): void {
getRTCRoomEngineManager().removeCoHostListener(liveID, eventName, listener);
}
const onCoHostStoreChanged = (eventName: string, res: string): void => {
try {
if (eventName === "connected") {
const data = safeJsonParse<LiveUserInfoParam[]>(res, []);
connected.value = data;
} else if (eventName === "invitees") {
const data = safeJsonParse<LiveUserInfoParam[]>(res, []);
invitees.value = data;
} else if (eventName === "applicant") {
const data = safeJsonParse<LiveUserInfoParam | null>(res, null);
applicant.value = data;
} else if (eventName === "candidates") {
const data = safeJsonParse<LiveUserInfoParam[]>(res, []);
candidates.value = data;
} else if (eventName === "coHostStatus") {
coHostStatus.value = JSON.parse(res);
}
} catch (error) {
console.error("onCoHostStoreChanged error:", error);
}
};
function bindEvent(liveID: string): void {
getRTCRoomEngineManager().on("coHostStoreChanged", onCoHostStoreChanged, liveID);
}
export function useCoHostState(liveID: string) {
bindEvent(liveID);
return {
coHostStatus, // 当前连线状态
connected, // 已连接的连线主播列表
invitees, // 被邀请连线的主播列表
applicant, // 当前申请连线的主播信息
// candidates, // 可邀请连线的候选主播列表: TODO待支持
requestHostConnection, // 请求连线
cancelHostConnection, // 取消连线请求
acceptHostConnection, // 接受连线请求
rejectHostConnection, // 拒绝连线请求
exitHostConnection, // 退出连线
addCoHostListener, // 添加连线事件监听
removeCoHostListener, // 移除连线事件监听
};
}
export default useCoHostState;

View File

@@ -0,0 +1,625 @@
/**
* @module DeviceState
* @module_description
* 设备状态管理模块
* 核心功能:管理摄像头、麦克风等音视频设备的控制,提供设备状态监控、权限检查等基础设备服务。
* 技术特点:支持多设备管理、设备状态实时监控、权限动态检查、设备故障自动恢复等高级功能。
* 业务价值:为直播系统提供稳定的设备基础,确保音视频采集的可靠性和用户体验。
* 应用场景:设备管理、权限控制、音视频采集、设备故障处理等基础技术场景。
*/
import { ref } from "vue";
import {
OpenLocalMicrophoneOptions, SetAudioRouteOptions, OpenLocalCameraOptions, SwitchCameraOptions,
UpdateVideoQualityOptions, SwitchMirrorOptions, VolumeOptions,
} from "@/uni_modules/tuikit-atomic-x";
import { getRTCRoomEngineManager } from "./rtcRoomEngine";
import permission from "../utils/permission";
import { callUTSFunction, safeJsonParse } from "../utils/utsUtils";
export const DeviceStatusCode = {
OFF: 0,
ON: 1,
} as const;
export type DeviceStatusCodeType =
(typeof DeviceStatusCode)[keyof typeof DeviceStatusCode];
export const DeviceStatus = {
OFF: "OFF",
ON: "ON",
} as const;
export type DeviceStatusType = (typeof DeviceStatus)[keyof typeof DeviceStatus];
export const DeviceErrorCode = {
NO_ERROR: 0,
NO_DEVICE_DETECTED: 1,
NO_SYSTEM_PERMISSION: 2,
NOT_SUPPORT_CAPTURE: 3,
OCCUPIED_ERROR: 4,
UNKNOWN_ERROR: 5,
} as const;
export type DeviceErrorCodeType =
(typeof DeviceErrorCode)[keyof typeof DeviceErrorCode];
export const DeviceErrorEnum = {
NO_ERROR: "NO_ERROR",
NO_DEVICE_DETECTED: "NO_DEVICE_DETECTED",
NO_SYSTEM_PERMISSION: "NO_SYSTEM_PERMISSION",
NOT_SUPPORT_CAPTURE: "NOT_SUPPORT_CAPTURE",
OCCUPIED_ERROR: "OCCUPIED_ERROR",
UNKNOWN_ERROR: "UNKNOWN_ERROR",
} as const;
export type DeviceErrorType = (typeof DeviceErrorEnum)[keyof typeof DeviceErrorEnum];
export const AudioOutput = {
SPEAKERPHONE: "SPEAKERPHONE",
EARPIECE: "EARPIECE",
} as const;
export type AudioOutputType = (typeof AudioOutput)[keyof typeof AudioOutput];
const DEVICE_STATUS_MAP: Record<DeviceStatusCodeType, DeviceStatusType> = {
[DeviceStatusCode.OFF]: DeviceStatus.OFF,
[DeviceStatusCode.ON]: DeviceStatus.ON,
} as const;
const DEVICE_ERROR_MAP: Record<DeviceErrorCodeType, DeviceErrorType> = {
[DeviceErrorCode.NO_ERROR]: DeviceErrorEnum.NO_ERROR,
[DeviceErrorCode.NO_DEVICE_DETECTED]: DeviceErrorEnum.NO_DEVICE_DETECTED,
[DeviceErrorCode.NO_SYSTEM_PERMISSION]: DeviceErrorEnum.NO_SYSTEM_PERMISSION,
[DeviceErrorCode.NOT_SUPPORT_CAPTURE]: DeviceErrorEnum.NOT_SUPPORT_CAPTURE,
[DeviceErrorCode.OCCUPIED_ERROR]: DeviceErrorEnum.OCCUPIED_ERROR,
[DeviceErrorCode.UNKNOWN_ERROR]: DeviceErrorEnum.UNKNOWN_ERROR,
} as const;
/**
* 麦克风开启状态
* @type {Ref<DeviceStatusType>}
* @memberof module:DeviceState
* @example
* import { useDeviceState } from '@/uni_modules/tuikit-atomic-x/state/DeviceState';
* const { microphoneStatus } = useDeviceState();
*
* // 监听麦克风状态变化
* watch(microphoneStatus, (newStatus) => {
* console.log('麦克风状态:', newStatus);
* if (newStatus === 'ON') {
* console.log('麦克风已打开');
* } else if (newStatus === 'OFF') {
* console.log('麦克风已关闭');
* }
* });
*/
const microphoneStatus = ref<DeviceStatusType>();
/**
* 麦克风最后一次错误状态
* @type {Ref<DeviceErrorType>}
* @memberof module:DeviceState
* @example
* import { useDeviceState } from '@/uni_modules/tuikit-atomic-x/state/DeviceState';
* const { microphoneLastError } = useDeviceState();
*
* // 监听麦克风错误状态
* watch(microphoneLastError, (newError) => {
* if (newError && newError !== 'NO_ERROR') {
* console.log('麦克风错误:', newError);
* }
* });
*/
const microphoneLastError = ref<DeviceErrorType>();
/**
* 是否有音频发布权限
* @type {Ref<boolean>}
* @memberof module:DeviceState
* @example
* import { useDeviceState } from '@/uni_modules/tuikit-atomic-x/state/DeviceState';
* const { hasPublishAudioPermission } = useDeviceState();
*
* // 检查是否有音频发布权限
* const hasPermission = hasPublishAudioPermission.value;
* if (!hasPermission) {
* console.log('没有音频发布权限');
* }
*/
const hasPublishAudioPermission = ref<boolean>(true);
/**
* 采集音量大小0-100
* @type {Ref<number>}
* @memberof module:DeviceState
* @example
* import { useDeviceState } from '@/uni_modules/tuikit-atomic-x/state/DeviceState';
* const { captureVolume } = useDeviceState();
*
* // 监听采集音量变化
* watch(captureVolume, (newVolume) => {
* console.log('采集音量:', newVolume);
* });
*/
const captureVolume = ref<number>(0);
/**
* 当前麦克风音量0-100
* @type {Ref<number>}
* @memberof module:DeviceState
* @example
* import { useDeviceState } from '@/uni_modules/tuikit-atomic-x/state/DeviceState';
* const { currentMicVolume } = useDeviceState();
*
* // 监听麦克风音量变化
* watch(currentMicVolume, (newVolume) => {
* console.log('当前麦克风音量:', newVolume);
* });
*/
const currentMicVolume = ref<number>(0);
/**
* 输出音量大小0-100
* @type {Ref<number>}
* @memberof module:DeviceState
* @example
* import { useDeviceState } from '@/uni_modules/tuikit-atomic-x/state/DeviceState';
* const { outputVolume } = useDeviceState();
*
* // 监听输出音量变化
* watch(outputVolume, (newVolume) => {
* console.log('输出音量:', newVolume);
* });
*/
const outputVolume = ref<number>(0);
/**
* 摄像头开启状态
* @type {Ref<DeviceStatusType>}
* @memberof module:DeviceState
* @example
* import { useDeviceState } from '@/uni_modules/tuikit-atomic-x/state/DeviceState';
* const { cameraStatus } = useDeviceState();
*
* // 监听摄像头状态变化
* watch(cameraStatus, (newStatus) => {
* console.log('摄像头状态:', newStatus);
* if (newStatus === 'ON') {
* console.log('摄像头已打开');
* }
* });
*/
const cameraStatus = ref<DeviceStatusType>();
/**
* 摄像头最后一次错误状态
* @type {Ref<DeviceErrorType>}
* @memberof module:DeviceState
* @example
* import { useDeviceState } from '@/uni_modules/tuikit-atomic-x/state/DeviceState';
* const { cameraLastError } = useDeviceState();
*
* // 监听摄像头错误状态
* watch(cameraLastError, (newError) => {
* if (newError && newError !== 'NO_ERROR') {
* console.log('摄像头错误:', newError);
* }
* });
*/
const cameraLastError = ref<DeviceErrorType>();
/**
* 是否为前置摄像头
* @type {Ref<boolean>}
* @memberof module:DeviceState
* @example
* import { useDeviceState } from '@/uni_modules/tuikit-atomic-x/state/DeviceState';
* const { isFrontCamera } = useDeviceState();
*
* // 检查当前是否为前置摄像头
* const isFront = isFrontCamera.value;
* if (isFront) {
* console.log('当前使用前置摄像头');
* }
*/
const isFrontCamera = ref<boolean>();
/**
* 本地镜像类型
* @type {Ref<string>}
* @memberof module:DeviceState
* @example
* import { useDeviceState } from '@/uni_modules/tuikit-atomic-x/state/DeviceState';
* const { localMirrorType } = useDeviceState();
*
* // 获取本地镜像类型
* const mirrorType = localMirrorType.value;
* console.log('本地镜像类型:', mirrorType);
*/
const localMirrorType = ref<string>('');
/**
* 本地视频质量设置
* @type {Ref<any>}
* @memberof module:DeviceState
* @example
* import { useDeviceState } from '@/uni_modules/tuikit-atomic-x/state/DeviceState';
* const { localVideoQuality } = useDeviceState();
*
* // 获取本地视频质量设置
* const quality = localVideoQuality.value;
* console.log('本地视频质量:', quality);
*/
const localVideoQuality = ref<any>();
/**
* 当前音频输出路由(扬声器/耳机)
* @type {Ref<AudioOutputType>}
* @memberof module:DeviceState
* @example
* import { useDeviceState } from '@/uni_modules/tuikit-atomic-x/state/DeviceState';
* const { currentAudioRoute } = useDeviceState();
*
* // 监听音频输出路由变化
* watch(currentAudioRoute, (newRoute) => {
* console.log('音频输出路由:', newRoute);
* if (newRoute === 'SPEAKERPHONE') {
* console.log('使用扬声器');
* } else if (newRoute === 'EARPIECE') {
* console.log('使用耳机');
* }
* });
*/
const currentAudioRoute = ref<AudioOutputType>();
/**
* 屏幕共享状态
* @type {Ref<DeviceStatusType>}
* @memberof module:DeviceState
* @example
* import { useDeviceState } from '@/uni_modules/tuikit-atomic-x/state/DeviceState';
* const { screenStatus } = useDeviceState();
*
* // 监听屏幕共享状态
* watch(screenStatus, (newStatus) => {
* console.log('屏幕共享状态:', newStatus);
* if (newStatus === 'ON') {
* console.log('屏幕共享已开启');
* }
* });
*/
const screenStatus = ref<DeviceStatusType>();
/**
* 网络信息状态
* @type {Ref<any>}
* @memberof module:DeviceState
* @example
* import { useDeviceState } from '@/uni_modules/tuikit-atomic-x/state/DeviceState';
* const { networkInfo } = useDeviceState();
*
* // 获取网络信息
* const info = networkInfo.value;
* console.log('网络信息:', info);
*/
const networkInfo = ref<any>();
/**
* @internal
*/
function mapStatusCodeToDeviceStatus(
statusCode: number
): DeviceStatusType | null {
const mappedStatus = DEVICE_STATUS_MAP[statusCode as DeviceStatusCodeType];
if (!mappedStatus) {
console.warn(`Unknown device status code: ${statusCode}`);
return null;
}
return mappedStatus;
}
/**
* @internal
*/
function mapErrorCodeToDeviceError(errorCode: number): DeviceErrorType | null {
const mappedError = DEVICE_ERROR_MAP[errorCode as DeviceErrorCodeType];
if (!mappedError) {
console.warn(`Unknown device error code: ${errorCode}`);
return null;
}
return mappedError;
}
/**
* 打开本地麦克风
* @param {OpenLocalMicrophoneOptions} [params] - 麦克风参数
* @returns {Promise<void>}
* @memberof module:DeviceState
* @example
* import { useDeviceState } from '@/uni_modules/tuikit-atomic-x/state/DeviceState';
* const { openLocalMicrophone } = useDeviceState();
* openLocalMicrophone({})
*/
async function openLocalMicrophone(params?: OpenLocalMicrophoneOptions): Promise<void> {
// @ts-ignore
if (uni.getSystemInfoSync().platform === "android") {
await permission.requestAndroidPermission(
"android.permission.RECORD_AUDIO"
);
}
callUTSFunction("openLocalMicrophone", params || {});
}
/**
* 关闭本地麦克风
* @returns {void}
* @memberof module:DeviceState
* @example
* import { useDeviceState } from '@/uni_modules/tuikit-atomic-x/state/DeviceState';
* const { closeLocalMicrophone } = useDeviceState();
* closeLocalMicrophone()
*/
function closeLocalMicrophone(): void {
callUTSFunction("closeLocalMicrophone");
}
/**
* 设置采集音量
* @param {VolumeOptions} params - 音量参数
* @returns {void}
* @memberof module:DeviceState
* @example
* import { useDeviceState } from '@/uni_modules/tuikit-atomic-x/state/DeviceState';
* const { setCaptureVolume } = useDeviceState();
* setCaptureVolume({ volume: 80 })
*/
function setCaptureVolume(params: VolumeOptions): void {
callUTSFunction("setCaptureVolume", params);
}
/**
* 设置输出音量
* @param {VolumeOptions} params - 音量参数
* @returns {void}
* @memberof module:DeviceState
* @example
* import { useDeviceState } from '@/uni_modules/tuikit-atomic-x/state/DeviceState';
* const { setOutputVolume } = useDeviceState();
* setOutputVolume({ volume: 90 })
*/
function setOutputVolume(params: VolumeOptions): void {
callUTSFunction("setOutputVolume", params);
}
/**
* 设置音频路由
* @param {SetAudioRouteOptions} params - 音频路由参数
* @returns {void}
* @memberof module:DeviceState
* @example
* // 设置为扬声器
* import { useDeviceState } from '@/uni_modules/tuikit-atomic-x/state/DeviceState';
* const { setAudioRoute } = useDeviceState();
* setAudioRoute({ route: 'SPEAKERPHONE' })
*/
function setAudioRoute(params: SetAudioRouteOptions): void {
callUTSFunction("setAudioRoute", params);
}
/**
* 打开本地摄像头
* @param {OpenLocalCameraOptions} [params] - 摄像头参数
* @returns {Promise<void>}
* @memberof module:DeviceState
* @example
* import { useDeviceState } from '@/uni_modules/tuikit-atomic-x/state/DeviceState';
* const { openLocalCamera } = useDeviceState();
* openLocalCamera({ isFront: true })
*/
async function openLocalCamera(params?: OpenLocalCameraOptions): Promise<void> {
// @ts-ignore
if (uni.getSystemInfoSync().platform === "android") {
await permission.requestAndroidPermission("android.permission.CAMERA");
}
callUTSFunction("openLocalCamera", params || {});
}
/**
* 关闭本地摄像头
* @returns {void}
* @memberof module:DeviceState
* @example
* import { useDeviceState } from '@/uni_modules/tuikit-atomic-x/state/DeviceState';
* const { closeLocalCamera } = useDeviceState();
* closeLocalCamera()
*/
function closeLocalCamera(): void {
callUTSFunction("closeLocalCamera");
}
/**
* 切换摄像头前后置
* @param {SwitchCameraOptions} params - 切换参数
* @returns {void}
* @memberof module:DeviceState
* @example
* // 切换到前置摄像头
* import { useDeviceState } from '@/uni_modules/tuikit-atomic-x/state/DeviceState';
* const { switchCamera } = useDeviceState();
* switchCamera({ isFront: true })
*/
function switchCamera(params: SwitchCameraOptions): void {
callUTSFunction("switchCamera", params);
}
/**
* 切换镜像
* @param {SwitchMirrorOptions} params - 镜像参数
* @returns {void}
* @memberof module:DeviceState
* @example
* // 设置自动镜像
* import { useDeviceState } from '@/uni_modules/tuikit-atomic-x/state/DeviceState';
* const { switchMirror } = useDeviceState();
* switchMirror({ mirrorType: 'AUTO' })
*/
function switchMirror(params: SwitchMirrorOptions): void {
callUTSFunction("switchMirror", params);
}
/**
* 更新视频质量
* @param {UpdateVideoQualityOptions} params - 视频质量参数
* @returns {void}
* @memberof module:DeviceState
* @example
* import { useDeviceState } from '@/uni_modules/tuikit-atomic-x/state/DeviceState';
* const { updateVideoQuality } = useDeviceState();
* updateVideoQuality({ quality: 'VIDEOQUALITY_1080P' })
*/
function updateVideoQuality(params: UpdateVideoQualityOptions): void {
callUTSFunction("updateVideoQuality", params);
}
/**
* 开始屏幕共享
* @returns {void}
* @memberof module:DeviceState
* @example
* import { useDeviceState } from '@/uni_modules/tuikit-atomic-x/state/DeviceState';
* const { startScreenShare } = useDeviceState();
* startScreenShare()
*/
function startScreenShare(): void {
callUTSFunction("startScreenShare");
}
/**
* 停止屏幕共享
* @returns {void}
* @memberof module:DeviceState
* @example
* import { useDeviceState } from '@/uni_modules/tuikit-atomic-x/state/DeviceState';
* const { stopScreenShare } = useDeviceState();
* stopScreenShare()
*/
function stopScreenShare(): void {
callUTSFunction("stopScreenShare");
}
const onDeviceStoreChanged = (eventName: string, res: string): void => {
try {
if (eventName === "microphoneStatus") {
const statusCode = safeJsonParse<number>(res, -1);
const status = mapStatusCodeToDeviceStatus(statusCode);
if (status) {
microphoneStatus.value = status;
} else {
console.error(`Invalid microphone status code received: ${statusCode}`);
}
} else if (eventName === "microphoneLastError") {
const errorCode = safeJsonParse<number>(res, -1);
const error = mapErrorCodeToDeviceError(errorCode);
if (error) {
microphoneLastError.value = error;
} else {
console.error(`Invalid microphone error code received: ${errorCode}`);
}
} else if (eventName === "captureVolume") {
const data = safeJsonParse<number>(res, 0);
captureVolume.value = data;
} else if (eventName === "currentMicVolume") {
const data = safeJsonParse<number>(res, 0);
currentMicVolume.value = data;
}
else if (eventName === "outputVolume") {
const data = safeJsonParse<number>(res, 0);
outputVolume.value = data;
}
else if (eventName === "cameraStatus") {
const statusCode = safeJsonParse<number>(res, -1);
const status = mapStatusCodeToDeviceStatus(statusCode);
if (status) {
cameraStatus.value = status;
} else {
console.error(`Invalid camera status code received: ${statusCode}`);
}
} else if (eventName === "cameraLastError") {
const errorCode = safeJsonParse<number>(res, -1);
const error = mapErrorCodeToDeviceError(errorCode);
if (error) {
cameraLastError.value = error;
} else {
console.error(`Invalid camera error code received: ${errorCode}`);
}
} else if (eventName === "isFrontCamera") {
const data = safeJsonParse<boolean>(res, true);
isFrontCamera.value = data;
} else if (eventName === "localMirrorType") {
localMirrorType.value = JSON.parse(res);
} else if (eventName === "localVideoQuality") {
const data = safeJsonParse<boolean>(res, false);
localVideoQuality.value = data;
}
else if (eventName === "currentAudioRoute") {
const data = safeJsonParse<AudioOutputType>(res, AudioOutput.SPEAKERPHONE);
currentAudioRoute.value = data;
} else if (eventName === "screenStatus") {
const statusCode = safeJsonParse<number>(res, -1);
const status = mapStatusCodeToDeviceStatus(statusCode);
if (status) {
screenStatus.value = status;
} else {
console.error(`Invalid screen status code received: ${statusCode}`);
}
} else if (eventName === "networkInfo") {
networkInfo.value = safeJsonParse<any>(res, {});
}
} catch (error) {
console.error("onDeviceStoreChanged error:", error);
}
};
function bindEvent(): void {
getRTCRoomEngineManager().on("deviceStoreChanged", onDeviceStoreChanged, "");
}
export function useDeviceState() {
bindEvent();
return {
microphoneStatus, // 麦克风开启状态
microphoneLastError, // 麦克风最后一次错误状态
hasPublishAudioPermission,// 是否有音频发布权限
captureVolume, // 采集音量大小
currentMicVolume, // 当前麦克风音量
outputVolume, // 输出音量大小
cameraStatus, // 摄像头开启状态
cameraLastError, // 摄像头最后一次错误状态
isFrontCamera, // 是否为前置摄像头
localMirrorType, // 本地镜像类型
localVideoQuality, // 本地视频质量设置
currentAudioRoute, // 当前音频输出路由
screenStatus, // 屏幕共享状态
networkInfo, // 网络信息状态
openLocalMicrophone, // 打开本地麦克风
closeLocalMicrophone, // 关闭本地麦克风
setCaptureVolume, // 设置采集音量
setOutputVolume, // 设置输出音量
setAudioRoute, // 设置音频路由
openLocalCamera, // 打开本地摄像头
closeLocalCamera, // 关闭本地摄像头
switchCamera, // 切换摄像头
switchMirror, // 切换镜像
updateVideoQuality, // 更新视频质量
startScreenShare, // 开始屏幕共享
stopScreenShare, // 停止屏幕共享
};
}
export default useDeviceState;

View File

@@ -0,0 +1,188 @@
/**
* @module GiftState
* @module_description
* 礼物系统管理模块
* 核心功能:处理礼物的发送、接收、礼物列表管理等功能,支持礼物分类、礼物动画、礼物统计等完整礼物经济系统。
* 技术特点:支持礼物动画渲染、礼物特效处理、礼物统计、礼物排行榜等高级功能。
* 业务价值:为直播平台提供核心的变现能力,支持礼物经济、虚拟货币等商业模式。
* 应用场景:礼物打赏、虚拟货币、礼物特效、礼物统计等商业化场景。
*/
import { ref } from "vue";
import { ILiveListener, RefreshUsableGiftsOptions, SendGiftOptions, SetLanguageOptions } from "@/uni_modules/tuikit-atomic-x";
import { getRTCRoomEngineManager } from "./rtcRoomEngine";
import { callUTSFunction, safeJsonParse } from "../utils/utsUtils";
/**
* 礼物参数类型定义
* @typedef {Object} GiftParam
* @property {String} giftID - 礼物唯一标识
* @property {String} name - 礼物名称
* @property {String} desc - 礼物描述
* @property {String} iconURL - 礼物图标URL
* @property {String} resourceURL - 礼物动画资源URL
* @property {number} level - 礼物等级
* @property {number} coins - 礼物价格(金币)
* @property {Map<String, String>} extensionInfo - 扩展信息
* @memberof module:GiftState
*/
export type GiftParam = {
giftID : String;
name : String;
desc : String;
iconURL : String;
resourceURL : String;
level : number;
coins : number;
extensionInfo : Map<String, String>;
};
/**
* 礼物分类参数类型定义
* @typedef {Object} GiftCategoryParam
* @property {string} [categoryID] - 分类ID
* @property {string} [name] - 分类名称
* @property {string} [desc] - 分类描述
* @property {Map<string, string>} [extensionInfo] - 扩展信息
* @property {GiftParam[]} [giftList] - 分类下的礼物列表
* @memberof module:GiftState
*/
export type GiftCategoryParam = {
categoryID ?: string;
name ?: string;
desc ?: string;
extensionInfo ?: Map<string, string>;
giftList ?: GiftParam[];
};
/**
* 可用礼物列表
* @type {Ref<GiftCategoryParam[]>}
* @memberof module:GiftState
* @example
* import { useGiftState } from '@/uni_modules/tuikit-atomic-x/state/GiftState';
* const { usableGifts } = useGiftState('your_live_id');
*
* // 监听可用礼物列表变化
* watch(usableGifts, (newGifts) => {
* if (newGifts && newGifts.length > 0) {
* console.log('可用礼物更新:', newGifts);
* newGifts.forEach(gift => {
* console.log('礼物ID:', gift.giftID);
* console.log('礼物名称:', gift.name);
* console.log('礼物价格:', gift.coins);
* });
* }
* });
*
* // 获取当前可用礼物列表
* const gifts = usableGifts.value;
* console.log('当前可用礼物数量:', gifts.length);
*/
const usableGifts = ref<GiftCategoryParam[]>([]);
/**
* 刷新可用礼物列表
* @param {RefreshUsableGiftsOptions} params - 刷新礼物列表参数
* @returns {void}
* @memberof module:GiftState
* @example
* import { useGiftState } from '@/uni_modules/tuikit-atomic-x/state/GiftState';
* const { refreshUsableGifts } = useGiftState("your_live_id");
* refreshUsableGifts({});
*/
function refreshUsableGifts(params : RefreshUsableGiftsOptions) : void {
callUTSFunction("refreshUsableGifts", params);
}
/**
* 发送礼物
* @param {SendGiftOptions} params - 发送礼物参数
* @returns {void}
* @memberof module:GiftState
* @example
* import { useGiftState } from '@/uni_modules/tuikit-atomic-x/state/GiftState';
* const { sendGift } = useGiftState("your_live_id")
* sendGift({ liveID: 'xxx', giftID: "gift001", count: 1 });
*/
function sendGift(params : SendGiftOptions) : void {
callUTSFunction("sendGift", params);
}
/**
* 设置礼物语言
* @param {SetLanguageOptions} params - 设置礼物语言参数
* @returns {void}
* @memberof module:GiftState
* @example
* import { useGiftState } from '@/uni_modules/tuikit-atomic-x/state/GiftState';
* const { setLanguage } = useGiftState("your_live_id")
* setLanguage({ liveID: 'xxx', language: "zh-CN",});
*/
function setLanguage(params : SetLanguageOptions) : void {
callUTSFunction("setLanguage", params);
}
/**
* 添加礼物事件监听器
* @param {string} liveID - 直播间ID
* @param {string} eventName - 事件名称,可选值: 'onReceiveGift'(收到礼物)
* @param {ILiveListener} listener - 事件监听器函数
* @returns {void}
* @memberof module:GiftState
* @example
* import { useGiftState } from '@/uni_modules/tuikit-atomic-x/state/GiftState';
* const { addGiftListener } = useGiftState("your_live_id")
* addGiftListener('your_live_id', 'onReceiveGift', {
* callback: (params) => {
* console.log('result:', params);
* }
* });
*/
function addGiftListener(liveID : string, eventName : string, listener : ILiveListener) : void {
getRTCRoomEngineManager().addGiftListener(liveID, eventName, listener);
}
/**
* 移除礼物事件监听器
* @param {string} liveID - 直播间ID
* @param {string} eventName - 事件名称,可选值: 'onReceiveGift'(收到礼物)
* @param {ILiveListener} listener - 事件监听器函数
* @returns {void}
* @memberof module:GiftState
* @example
* import { useGiftState } from '@/uni_modules/tuikit-atomic-x/state/GiftState';
* const { removeGiftListener } = useGiftState("your_live_id")
* removeGiftListener('your_live_id', 'onReceiveGift', giftListener);
*/
function removeGiftListener(liveID : string, eventName : string, listener : ILiveListener) : void {
getRTCRoomEngineManager().removeGiftListener(liveID, eventName, listener);
}
const onGiftStoreChanged = (eventName : string, res : string) : void => {
try {
if (eventName === "usableGifts") {
const data = safeJsonParse<GiftCategoryParam[]>(res, []);
usableGifts.value = data;
}
} catch (error) {
console.error("onGiftStoreChanged JSON parse error:", error);
}
};
function bindEvent(liveID : string) : void {
getRTCRoomEngineManager().on("giftStoreChanged", onGiftStoreChanged, liveID);
}
export function useGiftState(liveID : string) {
bindEvent(liveID);
return {
usableGifts, // 可用礼物列表
refreshUsableGifts, // 刷新可用礼物列表
sendGift, // 发送礼物
setLanguage, // 设置礼物语言
addGiftListener, // 添加礼物事件监听
removeGiftListener // 移除礼物事件监听
};
}
export default useGiftState;

View File

@@ -0,0 +1,108 @@
/**
* @module LikeState
* @module_description
* 点赞互动管理模块
* 核心功能:处理直播间的点赞功能,支持点赞发送、点赞统计、点赞事件监听等互动功能。
* 技术特点:支持高并发点赞处理、实时点赞统计、点赞动画效果、点赞排行榜等高级功能。
* 业务价值:为直播平台提供基础的互动能力,增强用户参与度和直播氛围。
* 应用场景:点赞互动、人气统计、互动效果、用户参与等基础互动场景。
*/
import { ref } from "vue";
import { ILiveListener, SendLikeOptions } from "@/uni_modules/tuikit-atomic-x";
import { getRTCRoomEngineManager } from "./rtcRoomEngine";
import { callUTSFunction, safeJsonParse } from "../utils/utsUtils";
/**
* 总点赞数量
* @type {Ref<number>}
* @memberof module:LikeState
* @example
* import { useLikeState } from '@/uni_modules/tuikit-atomic-x/state/LikeState';
* const { totalLikeCount } = useLikeState('your_live_id');
*
* // 监听总点赞数量变化
* watch(totalLikeCount, (newCount) => {
* console.log('总点赞数量:', newCount);
* });
*
* // 获取当前总点赞数量
* const likeCount = totalLikeCount.value;
* console.log('当前获赞数:', likeCount);
*/
const totalLikeCount = ref<number>(0);
/**
* 发送点赞
* @param {SendLikeOptions} params - 点赞参数
* @returns {void}
* @memberof module:LikeState
* @example
* import { useLikeState } from '@/uni_modules/tuikit-atomic-x/state/LikeState';
* const { sendLike } = useLikeState("your_live_id");
* sendLike({ count: 1 });
*/
function sendLike(params: SendLikeOptions): void {
callUTSFunction("sendLike", params);
}
/**
* 添加点赞事件监听
* @param {string} liveID - 直播ID
* @param {string} eventName - 事件名称,可选值: 'onReceiveLikesMessage'(收到点赞消息)
* @param {ILiveListener} listener - 事件回调函数
* @returns {void}
* @memberof module:LikeState
* @example
* import { useLikeState } from '@/uni_modules/tuikit-atomic-x/state/LikeState';
* const { addLikeListener } = useLikeState("your_live_id");
* addLikeListener('your_live_id', 'onReceiveLikesMessage', {
* callback: (params) => {
* console.log('result:', params);
* }
* });
*/
function addLikeListener(liveID: string, eventName: string, listener: ILiveListener): void {
getRTCRoomEngineManager().addLikeListener(liveID, eventName, listener);
}
/**
* 移除点赞事件监听
* @param {string} liveID - 直播ID
* @param {string} eventName - 事件名称,可选值: 'onReceiveLikesMessage'(收到点赞消息)
* @param {ILiveListener} listener - 事件回调函数
* @returns {void}
* @memberof module:LikeState
* @example
* import { useLikeState } from '@/uni_modules/tuikit-atomic-x/state/LikeState';
* const { removeLikeListener } = useLikeState("your_live_id");
* removeLikeListener('your_live_id', 'onReceiveLikesMessage', likeListener);
*/
function removeLikeListener(liveID: string, eventName: string, listener: ILiveListener): void {
getRTCRoomEngineManager().removeLikeListener(liveID, eventName, listener);
}
const onLikeStoreChanged = (eventName: string, res: string): void => {
try {
if (eventName === "totalLikeCount") {
const data = safeJsonParse<number>(res, 0);
totalLikeCount.value = data;
}
} catch (error) {
console.error("onLikeStoreChanged JSON parse error:", error);
}
};
function bindEvent(liveID: string): void {
getRTCRoomEngineManager().on("likeStoreChanged", onLikeStoreChanged, liveID);
}
export function useLikeState(liveID: string) {
bindEvent(liveID);
return {
totalLikeCount, // 总点赞数量
sendLike, // 发送点赞
addLikeListener, // 添加点赞事件监听
removeLikeListener, // 移除点赞事件监听
};
}
export default useLikeState;

View File

@@ -0,0 +1,204 @@
/**
* @module LiveAudienceState
* @module_description
* 直播间观众状态管理模块
* 核心功能:管理直播间观众列表,提供观众权限控制、管理员设置等直播间秩序维护功能。
* 技术特点:支持实时观众列表更新、权限分级管理、批量操作等高级功能,确保直播间秩序和用户体验。
* 业务价值:为直播平台提供完整的观众管理解决方案,支持大规模观众场景下的秩序维护。
* 应用场景:观众管理、权限控制、直播间秩序维护、观众互动管理等核心业务场景。
*/
import { ref } from "vue";
import {
FetchAudienceListOptions, SetAdministratorOptions, RevokeAdministratorOptions, KickUserOutOfRoomOptions,
DisableSendMessageOptions, LiveUserInfoParam, ILiveListener
} from "@/uni_modules/tuikit-atomic-x";
import { getRTCRoomEngineManager } from "./rtcRoomEngine";
import { callUTSFunction, safeJsonParse } from "../utils/utsUtils";
/**
* 直播间观众列表
* @type {Ref<LiveUserInfoParam[]>}
* @memberof module:LiveAudienceState
* @example
* import { useLiveAudienceState } from '@/uni_modules/tuikit-atomic-x/state/LiveAudienceState';
* const { audienceList } = useLiveAudienceState('your_live_id');
*
* // 监听观众列表变化
* watch(audienceList, (newAudienceList) => {
* if (newAudienceList && newAudienceList.length > 0) {
* console.log('观众列表更新:', newAudienceList);
* newAudienceList.forEach(audience => {
* console.log('观众ID:', audience.userID);
* });
* }
* });
*
* // 获取当前观众列表
* const audiences = audienceList.value;
* console.log('当前观众数:', audiences.length);
*/
const audienceList = ref<LiveUserInfoParam[]>([]);
/**
* 直播间观众数量
* @type {Ref<number>}
* @memberof module:LiveAudienceState
* @example
* import { useLiveAudienceState } from '@/uni_modules/tuikit-atomic-x/state/LiveAudienceState';
* const { audienceCount } = useLiveAudienceState('your_live_id');
*
* // 监听观众数量变化
* watch(audienceCount, (newCount) => {
* console.log('观众数量更新:', newCount);
* // 当观众数量达到某个阈值时可以进行特殊处理
* if (newCount >= 100) {
* console.log('直播热度很高观众数超过100');
* }
* });
*
* // 获取当前观众数量
* const count = audienceCount.value;
* console.log('当前观众数量:', count);
*/
const audienceCount = ref<number>(0);
/**
* 获取直播间观众列表
* @param {FetchAudienceListOptions} [params] - 获取观众列表参数
* @returns {void}
* @memberof module:LiveAudienceState
* @example
* import { useLiveAudienceState } from '@/uni_modules/tuikit-atomic-x/state/LiveAudienceState';
* const { fetchAudienceList } = useLiveAudienceState("your_live_id");
* fetchAudienceList();
*/
function fetchAudienceList(params ?: FetchAudienceListOptions) : void {
callUTSFunction("fetchAudienceList", params || {});
}
/**
* 设置管理员
* @param {SetAdministratorOptions} params - 设置管理员参数
* @returns {void}
* @memberof module:LiveAudienceState
* @example
* import { useLiveAudienceState } from '@/uni_modules/tuikit-atomic-x/state/LiveAudienceState';
* const { setAdministrator } = useLiveAudienceState("your_live_id");
* setAdministrator({ userID: 'user123' });
*/
function setAdministrator(params : SetAdministratorOptions) : void {
callUTSFunction("setAdministrator", params);
}
/**
* 撤销管理员权限
* @param {RevokeAdministratorOptions} params - 撤销管理员参数
* @returns {void}
* @memberof module:LiveAudienceState
* @example
* import { useLiveAudienceState } from '@/uni_modules/tuikit-atomic-x/state/LiveAudienceState';
* const { revokeAdministrator } = useLiveAudienceState("your_live_id");
* revokeAdministrator({ userID: 'user123' });
*/
function revokeAdministrator(params : RevokeAdministratorOptions) : void {
callUTSFunction("revokeAdministrator", params);
}
/**
* 将用户踢出直播间
* @param {KickUserOutOfRoomOptions} params - 踢出用户参数
* @returns {void}
* @memberof module:LiveAudienceState
* @example
* import { useLiveAudienceState } from '@/uni_modules/tuikit-atomic-x/state/LiveAudienceState';
* const { kickUserOutOfRoom } = useLiveAudienceState("your_live_id");
* kickUserOutOfRoom({ userID: 'user123' });
*/
function kickUserOutOfRoom(params : KickUserOutOfRoomOptions) : void {
callUTSFunction("kickUserOutOfRoom", params);
}
/**
* 禁用用户发送消息
* @param {DisableSendMessageOptions} params - 禁用发送消息参数
* @returns {void}
* @memberof module:LiveAudienceState
* @example
* import { useLiveAudienceState } from '@/uni_modules/tuikit-atomic-x/state/LiveAudienceState';
* const { disableSendMessage } = useLiveAudienceState("your_live_id");
* disableSendMessage({ userID: 'user123', disable: true });
*/
function disableSendMessage(params : DisableSendMessageOptions) : void {
callUTSFunction("disableSendMessage", params);
}
/**
* 添加观众事件监听
* @param {string} liveID - 直播间ID
* @param {string} eventName - 事件名称,可选值: 'onAudienceJoined'(观众加入)<br>'onAudienceLeft'(观众离开)
* @param {ILiveListener} listener - 事件回调函数
* @returns {void}
* @memberof module:LiveAudienceState
* @example
* import { useLiveAudienceState } from '@/uni_modules/tuikit-atomic-x/state/LiveAudienceState';
* const { addAudienceListener } = useLiveAudienceState("your_live_id");
* addAudienceListener('your_live_id', 'onAudienceJoined', {
* callback: (params) => {
* console.log('result:', params);
* }
* });
*/
function addAudienceListener(liveID : string, eventName : string, listener : ILiveListener) : void {
getRTCRoomEngineManager().addAudienceListener(liveID, eventName, listener);
}
/**
* 移除观众事件监听
* @param {string} liveID - 直播间ID
* @param {string} eventName - 事件名称,可选值: 'onAudienceJoined'(观众加入)<br>'onAudienceLeft'(观众离开)
* @param {ILiveListener} listener - 事件回调函数
* @returns {void}
* @memberof module:LiveAudienceState
* @example
* import { useLiveAudienceState } from '@/uni_modules/tuikit-atomic-x/state/LiveAudienceState';
* const { removeAudienceListener } = useLiveAudienceState("your_live_id");
* removeAudienceListener('your_live_id', 'onAudienceJoined', audienceListener);
*/
function removeAudienceListener(liveID : string, eventName : string, listener : ILiveListener) : void {
getRTCRoomEngineManager().removeAudienceListener(liveID, eventName, listener);
}
const onLiveAudienceStoreChanged = (eventName : string, res : string) : void => {
try {
if (eventName === "audienceList") {
audienceList.value = safeJsonParse<LiveUserInfoParam[]>(res, []);
} else if (eventName === "audienceCount") {
audienceCount.value = safeJsonParse<number>(res, 0);
}
} catch (error) {
console.error("onLiveAudienceStoreChanged error:", error);
}
};
function bindEvent(liveID : string) : void {
getRTCRoomEngineManager().on("liveAudienceStoreChanged", onLiveAudienceStoreChanged, liveID);
}
export function useLiveAudienceState(liveID : string) {
bindEvent(liveID);
return {
audienceList, // 直播间观众列表
audienceCount, // 直播间观众数量
fetchAudienceList, // 获取观众列表
setAdministrator, // 设置管理员
revokeAdministrator, // 撤销管理员权限
kickUserOutOfRoom, // 将用户踢出直播间
disableSendMessage, // 禁用用户发送消息
addAudienceListener, // 添加观众事件监听
removeAudienceListener, // 移除观众事件监听
};
}
export default useLiveAudienceState;

View File

@@ -0,0 +1,281 @@
/**
* @module LiveListState
* @module_description
* 直播列表状态管理模块
* 核心功能:管理直播间的完整生命周期,包括创建、加入、离开、结束等核心业务流程。
* 技术特点支持分页加载、实时状态同步、直播信息动态更新采用响应式数据管理确保UI与数据状态实时同步。
* 业务价值:为直播平台提供核心的直播间管理能力,支持大规模并发直播场景,是直播业务的基础设施。
* 应用场景:直播列表展示、直播间创建、直播状态管理、直播数据统计等核心业务场景。
*/
import { ref } from "vue";
import {
LiveInfoParam, FetchLiveListOptions, CreateLiveOptions, JoinLiveOptions, LeaveLiveOptions, EndLiveOptions, UpdateLiveInfoOptions, UpdateLiveMetaDataOptions, CallExperimentalAPIOptions, ILiveListener,
} from "@/uni_modules/tuikit-atomic-x";
import { getRTCRoomEngineManager } from "./rtcRoomEngine";
import { callUTSFunction, safeJsonParse } from "../utils/utsUtils";
/**
* 直播列表数据
* @type {Ref<LiveInfoParam[]>}
* @memberof module:LiveListState
* @example
* import { useLiveListState } from '@/uni_modules/tuikit-atomic-x/state/LiveListState';
* const { liveList } = useLiveListState();
*
* // 监听直播列表变化
* watch(liveList, (newList) => {
* if (newList && newList.length > 0) {
* console.log('直播列表更新:', newList);
* newList.forEach(live => {
* console.log('直播ID:', live.liveID);
* console.log('直播标题:', live.title);
* });
* }
* });
*
* // 获取当前直播列表
* const currentList = liveList.value;
* console.log('当前直播数量:', currentList.length);
*/
const liveList = ref<LiveInfoParam[]>([]);
/**
* 直播列表游标,用于分页加载
* @type {Ref<string>}
* @memberof module:LiveListState
* @example
* import { useLiveListState } from '@/uni_modules/tuikit-atomic-x/state/LiveListState';
* const { liveListCursor } = useLiveListState();
*
* // 监听游标变化用于分页加载
* watch(liveListCursor, (newCursor) => {
* console.log('直播列表游标更新:', newCursor);
* // 当游标更新时,可以获取下一页数据
* if (newCursor) {
* console.log('加载下一页直播列表');
* }
* });
*
* // 获取当前游标
* const cursor = liveListCursor.value;
* if (cursor) {
* console.log('当前分页游标:', cursor);
* }
*/
const liveListCursor = ref<string>("");
/**
* 当前直播信息
* @type {Ref<LiveInfoParam | null>}
* @memberof module:LiveListState
* @example
* import { useLiveListState } from '@/uni_modules/tuikit-atomic-x/state/LiveListState';
* const { currentLive } = useLiveListState();
*
* // 监听当前直播信息变化
* watch(currentLive, (newLive) => {
* if (newLive) {
* console.log('当前直播信息更新:', newLive);
* console.log('直播ID:', newLive.liveID);
* console.log('直播标题:', newLive.title);
* console.log('观看人数:', newLive.viewerCount);
* }
* });
*
* // 获取当前直播信息
* const live = currentLive.value;
* if (live) {
* console.log('当前进入的直播:', live.title);
* }
*/
const currentLive = ref<LiveInfoParam | null>(null);
/**
* 获取直播列表
* @param {FetchLiveListOptions} params - 获取参数
* @returns {void}
* @memberof module:LiveListState
* @example
* import { useLiveListState } from '@/uni_modules/tuikit-atomic-x/state/LiveListState';
* const { fetchLiveList } = useLiveListState();
* fetchLiveList({ cursor: "", count: 20 });
*/
function fetchLiveList(params : FetchLiveListOptions) : void {
callUTSFunction("fetchLiveList", params);
}
/**
* 创建直播间
* @param {CreateLiveOptions} params - 创建参数
* @returns {void}
* @memberof module:LiveListState
* @example
* import { useLiveListState } from '@/uni_modules/tuikit-atomic-x/state/LiveListState';
* const { createLive } = useLiveListState();
* createLive({ title: 'my live', coverUrl: 'https://example.com/cover.jpg'});
*/
function createLive(params : CreateLiveOptions) : void {
callUTSFunction("createLive", params);
}
/**
* 加入直播间
* @param {JoinLiveOptions} params - 加入参数
* @returns {void}
* @memberof module:LiveListState
* @example
* import { useLiveListState } from '@/uni_modules/tuikit-atomic-x/state/LiveListState';
* const { joinLive } = useLiveListState();
* joinLive({ liveID: 'host_live_id' });
*/
function joinLive(params : JoinLiveOptions) : void {
callUTSFunction("joinLive", params);
}
/**
* 离开直播间
* @param {LeaveLiveOptions} [params] - 离开参数(可选)
* @returns {void}
* @memberof module:LiveListState
* @example
* import { useLiveListState } from '@/uni_modules/tuikit-atomic-x/state/LiveListState';
* const { leaveLive } = useLiveListState();
* leaveLive();
*/
function leaveLive(params ?: LeaveLiveOptions) : void {
callUTSFunction("leaveLive", params || {});
}
/**
* 结束直播
* @param {EndLiveOptions} [params] - 结束参数(可选)
* @returns {void}
* @memberof module:LiveListState
* @example
* import { useLiveListState } from '@/uni_modules/tuikit-atomic-x/state/LiveListState';
* const { endLive } = useLiveListState();
* endLive();
*/
function endLive(params ?: EndLiveOptions) : void {
callUTSFunction("endLive", params || {});
}
/**
* 更新直播信息
* @param {UpdateLiveInfoOptions} params - 更新参数
* @returns {void}
* @memberof module:LiveListState
* @example
* import { useLiveListState } from '@/uni_modules/tuikit-atomic-x/state/LiveListState';
* const { updateLiveInfo } = useLiveListState();
* updateLiveInfo({ liveID: 'your_live_id', title: 'new title' });
*/
function updateLiveInfo(params : UpdateLiveInfoOptions) : void {
callUTSFunction("updateLiveInfo", params);
}
/**
* 更新直播元数据
* @param {UpdateLiveMetaDataOptions} params - 更新直播元数据, 监听 currentLive 获取更新结果
* @returns {void}
* @memberof module:LiveListState
* @example
* import { updateLiveMetaData } from '@/uni_modules/tuikit-atomic-x/state/LiveListState';
* const { updateLiveMetaData } = useLiveListState();
* updateLiveMetaData({metaData: '['key': 'value']' });
*/
function updateLiveMetaData(params : UpdateLiveMetaDataOptions) : void {
callUTSFunction("updateLiveMetaData", params);
}
function callExperimentalAPI(params : CallExperimentalAPIOptions) : void {
const defaultCallback = {
onResponse: (res ?: string) => {
console.log("onExperimentalAPIResponse: ", res);
},
};
const finalParams = {
...params,
onResponse: params.onResponse || defaultCallback.onResponse,
};
console.log("callExperimentalAPI", finalParams);
getRTCRoomEngineManager().callExperimentalAPI(finalParams);
}
/**
* 添加直播列表事件监听
* @param {string} eventName - 事件名称,可选值: 'onLiveEnded'(直播结束)<br>'onKickedOutOfLive'(被踢出直播间)
* @param {ILiveListener} listener - 事件回调函数
* @returns {void}
* @memberof module:LiveListState
* @example
* import { useLiveListState } from '@/uni_modules/tuikit-atomic-x/state/LiveListState';
* const { addLiveListListener } = useLiveListState();
* addLiveListListener('onLiveEnded', {
* callback: (params) => {
* console.log('result:', params);
* }
* });
*/
function addLiveListListener(eventName : string, listener : ILiveListener) : void {
getRTCRoomEngineManager().addLiveListListener(eventName, listener);
}
/**
* 移除直播列表事件监听
* @param {string} eventName - 事件名称,可选值: 'onLiveEnded'(直播结束)<br>'onKickedOutOfLive'(被踢出直播间)
* @param {ILiveListener} listener - 事件回调函数
* @returns {void}
* @memberof module:LiveListState
* @example
* import { useLiveListState } from '@/uni_modules/tuikit-atomic-x/state/LiveListState';
* const { removeLiveListListener } = useLiveListState();
* removeLiveListListener('onLiveEnded', liveEndedListener);
*/
function removeLiveListListener(eventName : string, listener : ILiveListener) : void {
getRTCRoomEngineManager().removeLiveListListener(eventName, listener);
}
const onLiveStoreChanged = (eventName : string, res : string) : void => {
try {
if (eventName === "liveList") {
const data = safeJsonParse<LiveInfoParam[]>(res, []);
liveList.value = data;
} else if (eventName === "liveListCursor") {
const data = safeJsonParse<string>(res, "");
liveListCursor.value = data;
} else if (eventName === "currentLive") {
const data = safeJsonParse<LiveInfoParam | null>(res, null);
currentLive.value = data;
}
} catch (error) {
console.error("onLiveStoreChanged error:", error);
}
};
function bindEvent() : void {
getRTCRoomEngineManager().on("liveStoreChanged", onLiveStoreChanged, "");
}
export function useLiveListState() {
bindEvent();
return {
liveList, // 直播列表数据
liveListCursor, // 直播列表分页游标
currentLive, // 当前直播信息
fetchLiveList, // 获取直播列表
createLive, // 创建直播
joinLive, // 加入直播
leaveLive, // 离开直播
endLive, // 结束直播
updateLiveInfo, // 更新直播信息
updateLiveMetaData, // 更新直播元数据
callExperimentalAPI,
addLiveListListener, // 添加事件监听
removeLiveListListener, // 移除事件监听
};
}
export default useLiveListState;

View File

@@ -0,0 +1,439 @@
/**
* @module LiveSeatState
* @module_description
* 直播间麦位管理模块
* 核心功能:实现多人连麦场景下的座位控制,支持复杂的座位状态管理和音视频设备控制。
* 技术特点:基于音视频技术,支持多路音视频流管理,提供座位锁定、设备控制、权限管理等高级功能。
* 业务价值为多人互动直播提供核心技术支撑支持PK、连麦、多人游戏等丰富的互动场景。
* 应用场景多人连麦、主播PK、互动游戏、在线教育、会议直播等需要多人音视频互动的场景。
*/
import { ref } from "vue";
import {
TakeSeatOptions, LeaveSeatOptions, MuteMicrophoneOptions, UnmuteMicrophoneOptions, KickUserOutOfSeatOptions,
MoveUserToSeatOptions, UnlockSeatOptions, SeatUserInfoParam, LockSeatOptions,
OpenRemoteCameraOptions, CloseRemoteCameraOptions, OpenRemoteMicrophoneOptions, CloseRemoteMicrophoneOptions, ILiveListener,
} from "@/uni_modules/tuikit-atomic-x";
import { getRTCRoomEngineManager } from "./rtcRoomEngine";
import { callUTSFunction, safeJsonParse } from "../utils/utsUtils";
/**
* 区域信息参数类型定义
* @typedef {Object} RegionInfoParams
* @property {number} x X坐标位置
* @property {number} y Y坐标位置
* @property {number} w 宽度
* @property {number} h 高度
* @property {number} zorder 层级顺序
* @memberof module:LiveSeatState
*/
export type RegionInfoParams = {
x : number;
y : number;
w : number;
h : number;
zorder : number;
}
/**
* 直播画布参数类型定义
* @typedef {Object} LiveCanvasParams
* @property {number} w 画布宽度
* @property {number} h 画布高度
* @property {string} [background] 背景色(可选)
* @memberof module:LiveSeatState
*/
export type LiveCanvasParams = {
w : number;
h : number;
background ?: string;
}
/**
* 座位信息类型定义
* @typedef {Object} SeatInfo
* @property {number} index 座位索引
* @property {boolean} isLocked 是否锁定
* @property {SeatUserInfoParam} userInfo 座位上用户信息
* @property {RegionInfoParams} region 座位区域信息
* @memberof module:LiveSeatState
*/
export type SeatInfo = {
index : number;
isLocked : boolean;
userInfo : SeatUserInfoParam;
region : RegionInfoParams;
}
/**
* 座位列表
* @type {Ref<SeatInfo[]>}
* @memberof module:LiveSeatState
* @example
* import { useLiveSeatState } from '@/uni_modules/tuikit-atomic-x/state/LiveSeatState';
* const { seatList } = useLiveSeatState('your_live_id');
*
* // 监听座位列表变化
* watch(seatList, (newSeatList) => {
* if (newSeatList && newSeatList.length > 0) {
* console.log('座位列表更新:', newSeatList);
* newSeatList.forEach(seat => {
* console.log('座位索引:', seat.index);
* console.log('座位是否锁定:', seat.isLocked);
* if (seat.userInfo) {
* console.log('座位上用户ID:', seat.userInfo.userID);
* }
* });
* }
* });
*
* // 获取当前座位列表
* const seats = seatList.value;
* console.log('当前座位数:', seats.length);
*/
const seatList = ref<SeatInfo[]>([]);
/**
* 画布信息
* @type {Ref<LiveCanvasParams | null>}
* @memberof module:LiveSeatState
* @example
* import { useLiveSeatState } from '@/uni_modules/tuikit-atomic-x/state/LiveSeatState';
* const { canvas } = useLiveSeatState('your_live_id');
*
* // 监听画布信息变化
* watch(canvas, (newCanvas) => {
* if (newCanvas) {
* console.log('画布信息更新:', newCanvas);
* }
* });
*
* // 获取当前画布信息
* const currentCanvas = canvas.value;
* if (currentCanvas) {
* console.log('当前画布分辨率:', currentCanvas.w, 'x', currentCanvas.h);
* }
*/
const canvas = ref<LiveCanvasParams | null>(null);
/**
* 正在说话的用户列表
* @type {Ref<Map<string, number> | null>}
* @memberof module:LiveSeatState
* @example
* import { useLiveSeatState } from '@/uni_modules/tuikit-atomic-x/state/LiveSeatState';
* const { speakingUsers } = useLiveSeatState('your_live_id');
*
* // 监听正在说话的用户列表变化
* watch(speakingUsers, (newSpeakingUsers) => {
* if (newSpeakingUsers && newSpeakingUsers.size > 0) {
* console.log('正在说话的用户更新');
* newSpeakingUsers.forEach((volume, userID) => {
* console.log('用户ID:', userID);
* console.log('音量:', volume);
* });
* }
* });
*
* // 获取当前正在说话的用户数量
* const users = speakingUsers.value;
* if (users) {
* console.log('当前说话的用户数:', users.size);
* }
*/
const speakingUsers = ref<Map<string, number> | null>(null);
/**
* 用户上麦
* @param {TakeSeatOptions} params - 上麦参数
* @returns {void}
* @memberof module:LiveSeatState
* @example
* import { useLiveSeatState } from '@/uni_modules/tuikit-atomic-x/state/LiveSeatState';
* const { takeSeat } = useLiveSeatState('your_live_id');
* takeSeat({
* seatIndex: 1,
* onSuccess: () => console.log('上麦成功'),
* onError: (error) => console.error('上麦失败:', error)
* });
*/
function takeSeat(params : TakeSeatOptions) : void {
callUTSFunction("takeSeat", params);
}
/**
* 用户下麦
* @param {LeaveSeatOptions} params - 下麦参数
* @returns {void}
* @memberof module:LiveSeatState
* @example
* import { useLiveSeatState } from '@/uni_modules/tuikit-atomic-x/state/LiveSeatState';
* const { leaveSeat } = useLiveSeatState('your_live_id');
* leaveSeat({
* onSuccess: () => console.log('下麦成功'),
* onError: (error) => console.error('下麦失败:', error)
* });
*/
function leaveSeat(params : LeaveSeatOptions) : void {
callUTSFunction("leaveSeat", params);
}
/**
* 静音麦克风
* @param {MuteMicrophoneOptions} params - 静音参数
* @returns {void}
* @memberof module:LiveSeatState
* @example
* import { useLiveSeatState } from '@/uni_modules/tuikit-atomic-x/state/LiveSeatState';
* const { muteMicrophone } = useLiveSeatState('your_live_id');
* muteMicrophone({
* onSuccess: () => console.log('麦克风静音成功'),
* onError: (error) => console.error('麦克风静音失败:', error)
* });
*/
function muteMicrophone(params : MuteMicrophoneOptions) : void {
callUTSFunction("muteMicrophone", params);
}
/**
* 取消静音麦克风
* @param {UnmuteMicrophoneOptions} params - 取消静音参数
* @returns {void}
* @memberof module:LiveSeatState
* @example
* import { useLiveSeatState } from '@/uni_modules/tuikit-atomic-x/state/LiveSeatState';
* const { unmuteMicrophone } = useLiveSeatState('your_live_id');
* unmuteMicrophone({
* onSuccess: () => console.log('麦克风取消静音成功'),
* onError: (error) => console.error('麦克风取消静音失败:', error)
* });
*/
function unmuteMicrophone(params : UnmuteMicrophoneOptions) : void {
callUTSFunction("unmuteMicrophone", params);
}
/**
* 将用户踢出座位
* @param {KickUserOutOfSeatOptions} params - 踢出参数
* @returns {void}
* @memberof module:LiveSeatState
* @example
* import { useLiveSeatState } from '@/uni_modules/tuikit-atomic-x/state/LiveSeatState';
* const { kickUserOutOfSeat } = useLiveSeatState('your_live_id');
* kickUserOutOfSeat({
* seatIndex: 1,
* onSuccess: () => console.log('踢出用户成功'),
* onError: (error) => console.error('踢出用户失败:', error)
* });
*/
function kickUserOutOfSeat(params : KickUserOutOfSeatOptions) : void {
callUTSFunction("kickUserOutOfSeat", params);
}
/**
* 移动用户到指定座位
* @param {MoveUserToSeatOptions} params - 移动参数
* @returns {void}
* @memberof module:LiveSeatState
* @example
* import { useLiveSeatState } from '@/uni_modules/tuikit-atomic-x/state/LiveSeatState';
* const { moveUserToSeat } = useLiveSeatState('your_live_id');
* moveUserToSeat({
* fromSeatIndex: 1,
* toSeatIndex: 3,
* onSuccess: () => console.log('用户移动成功'),
* onError: (error) => console.error('用户移动失败:', error)
* });
*/
function moveUserToSeat(params : MoveUserToSeatOptions) : void {
callUTSFunction("moveUserToSeat", params);
}
/**
* 锁定座位
* @param {LockSeatOptions} params - 锁定参数
* @returns {void}
* @memberof module:LiveSeatState
* @example
* import { useLiveSeatState } from '@/uni_modules/tuikit-atomic-x/state/LiveSeatState';
* const { lockSeat } = useLiveSeatState('your_live_id');
* lockSeat({
* seatIndex: 2,
* onSuccess: () => console.log('座位锁定成功'),
* onError: (error) => console.error('座位锁定失败:', error)
* });
*/
function lockSeat(params : LockSeatOptions) : void {
callUTSFunction("lockSeat", params);
}
/**
* 解锁座位
* @param {UnlockSeatOptions} params - 解锁参数
* @returns {void}
* @memberof module:LiveSeatState
* @example
* import { useLiveSeatState } from '@/uni_modules/tuikit-atomic-x/state/LiveSeatState';
* const { unlockSeat } = useLiveSeatState('your_live_id');
* unlockSeat({
* seatIndex: 2,
* onSuccess: () => console.log('座位解锁成功'),
* onError: (error) => console.error('座位解锁失败:', error)
* });
*/
function unlockSeat(params : UnlockSeatOptions) : void {
callUTSFunction("unlockSeat", params);
}
/**
* 开启远程摄像头
* @param {OpenRemoteCameraOptions} params - 开启摄像头参数
* @returns {void}
* @memberof module:LiveSeatState
* @example
* import { useLiveSeatState } from '@/uni_modules/tuikit-atomic-x/state/LiveSeatState';
* const { openRemoteCamera } = useLiveSeatState('your_live_id');
* openRemoteCamera({
* seatIndex: 1,
* onSuccess: () => console.log('远程摄像头开启成功'),
* onError: (error) => console.error('远程摄像头开启失败:', error)
* });
*/
function openRemoteCamera(params : OpenRemoteCameraOptions) : void {
callUTSFunction("openRemoteCamera", params);
}
/**
* 关闭远程摄像头
* @param {CloseRemoteCameraOptions} params - 关闭摄像头参数
* @returns {void}
* @memberof module:LiveSeatState
* @example
* import { useLiveSeatState } from '@/uni_modules/tuikit-atomic-x/state/LiveSeatState';
* const { closeRemoteCamera } = useLiveSeatState('your_live_id');
* closeRemoteCamera({
* seatIndex: 1,
* onSuccess: () => console.log('远程摄像头关闭成功'),
* onError: (error) => console.error('远程摄像头关闭失败:', error)
* });
*/
function closeRemoteCamera(params : CloseRemoteCameraOptions) : void {
callUTSFunction("closeRemoteCamera", params);
}
/**
* 开启远程麦克风
* @param {OpenRemoteMicrophoneOptions} params - 开启麦克风参数
* @returns {void}
* @memberof module:LiveSeatState
* @example
* import { useLiveSeatState } from '@/uni_modules/tuikit-atomic-x/state/LiveSeatState';
* const { openRemoteMicrophone } = useLiveSeatState('your_live_id');
* openRemoteMicrophone({
* seatIndex: 1,
* onSuccess: () => console.log('远程麦克风开启成功'),
* onError: (error) => console.error('远程麦克风开启失败:', error)
* });
*/
function openRemoteMicrophone(params : OpenRemoteMicrophoneOptions) : void {
callUTSFunction("openRemoteMicrophone", params);
}
/**
* 关闭远程麦克风
* @param {CloseRemoteMicrophoneOptions} params - 关闭麦克风参数
* @returns {void}
* @memberof module:LiveSeatState
* @example
* import { useLiveSeatState } from '@/uni_modules/tuikit-atomic-x/state/LiveSeatState';
* const { closeRemoteMicrophone } = useLiveSeatState('your_live_id');
* closeRemoteMicrophone({
* seatIndex: 1,
* onSuccess: () => console.log('远程麦克风关闭成功'),
* onError: (error) => console.error('远程麦克风关闭失败:', error)
* });
*/
function closeRemoteMicrophone(params : CloseRemoteMicrophoneOptions) : void {
callUTSFunction("closeRemoteMicrophone", params);
}
/**
* 添加座位事件监听
* @param {string} liveID - 直播间ID
* @param {string} eventName - 事件名称,可选值: 'onLocalCameraOpenedByAdmin'(本地摄像头被管理员开启)<br>'onLocalCameraClosedByAdmin'(本地摄像头被管理员关闭)<br>'onLocalMicrophoneOpenedByAdmin'(本地麦克风被管理员开启)<br>'onLocalMicrophoneClosedByAdmin'(本地麦克风被管理员关闭)
* @param {ILiveListener} listener - 事件处理函数
* @returns {void}
* @memberof module:LiveSeatState
* @example
* import { useLiveSeatState } from '@/uni_modules/tuikit-atomic-x/state/LiveSeatState';
* const { addLiveSeatEventListener } = useLiveSeatState('your_live_id');
* addLiveSeatEventListener('your_live_id', 'onLocalCameraOpenedByAdmin', {
* callback: (params) => {
* console.log('result:', params);
* }
* });
*/
function addLiveSeatEventListener(liveID : string, eventName : string, listener : ILiveListener) : void {
getRTCRoomEngineManager().addLiveSeatEventListener(liveID, eventName, listener);
}
/**
* 移除座位事件监听
* @param {string} liveID - 直播间ID
* @param {string} eventName - 事件名称,可选值: 'onLocalCameraOpenedByAdmin'(本地摄像头被管理员开启)<br>'onLocalCameraClosedByAdmin'(本地摄像头被管理员关闭)<br>'onLocalMicrophoneOpenedByAdmin'(本地麦克风被管理员开启)<br>'onLocalMicrophoneClosedByAdmin'(本地麦克风被管理员关闭)
* @param {ILiveListener} listener - 事件处理函数
* @returns {void}
* @memberof module:LiveSeatState
* @example
* import { useLiveSeatState } from '@/uni_modules/tuikit-atomic-x/state/LiveSeatState';
* const { removeLiveSeatEventListener } = useLiveSeatState('your_live_id');
* removeLiveSeatEventListener('your_live_id', 'onLocalCameraOpenedByAdmin', seatListener);
*/
function removeLiveSeatEventListener(liveID : string, eventName : string, listener : ILiveListener) : void {
getRTCRoomEngineManager().removeLiveSeatEventListener(liveID, eventName, listener);
}
const onLiveSeatStoreChanged = (eventName : string, res : string) : void => {
try {
if (eventName === "seatList") {
seatList.value = safeJsonParse<SeatInfo[]>(res, []);
} else if (eventName === "canvas") {
canvas.value = safeJsonParse<LiveCanvasParams | null>(res, null);
} else if (eventName === "speakingUsers") {
speakingUsers.value = safeJsonParse<Map<string, number> | null>(res, null);
}
} catch (error) {
console.error("onLiveSeatStoreChanged error:", error);
}
};
function bindEvent(liveID : string) : void {
getRTCRoomEngineManager().on("liveSeatStoreChanged", onLiveSeatStoreChanged, liveID);
}
export function useLiveSeatState(liveID : string) {
bindEvent(liveID);
return {
seatList, // 座位列表
canvas, // 画布信息
speakingUsers, // 正在说话的用户列表
takeSeat, // 用户上麦
leaveSeat, // 用户下麦
muteMicrophone, // 静音麦克风
unmuteMicrophone, // 取消静音麦克风
kickUserOutOfSeat, // 将用户踢出座位
moveUserToSeat, // 移动用户到指定座位
lockSeat, // 锁定座位
unlockSeat, // 解锁座位
openRemoteCamera, // 开启远程摄像头
closeRemoteCamera, // 关闭远程摄像头
openRemoteMicrophone, // 开启远程麦克风
closeRemoteMicrophone, // 关闭远程麦克风
addLiveSeatEventListener, // 添加座位事件监听
removeLiveSeatEventListener, // 移除座位事件监听
};
}
export default useLiveSeatState;

View File

@@ -0,0 +1,58 @@
/**
* @module LiveSummaryState
* @module_description
* 统计信息状态管理模块
* 核心功能:统计和展示直播过程中的关键数据,包括观看人数、点赞数、礼物数等实时统计。
* 技术特点:支持实时数据采集、数据聚合、统计分析等功能,提供完整的直播数据视图。
* 业务价值:为直播平台提供数据分析能力,支持直播效果评估和优化改进。
* 应用场景:直播数据展示、主播分析、流量统计、商业数据报表等数据分析场景。
*/
import { ref } from "vue";
import { getRTCRoomEngineManager } from "./rtcRoomEngine";
/**
* 直播间统计信息
* @type {Ref<any>}
* @memberof module:LiveSummaryState
* @example
* import { useLiveSummaryState } from '@/uni_modules/tuikit-atomic-x/state/LiveSummaryState';
* const { summaryData } = useLiveSummaryState('your_live_id');
*
* // 监听统计数据变化
* watch(summaryData, (newData) => {
* if (newData) {
* console.log('直播统计数据更新:', newData);
* }
* });
*
* // 获取当前统计数据
* const data = summaryData.value;
* if (data) {
* console.log('当前直播统计数据:', data);
* }
*/
const summaryData = ref<any>();
const onLiveSummaryStoreChanged = (eventName : string, res : string) : void => {
try {
if (eventName === "summaryData") {
const data = JSON.parse(res);
summaryData.value = data;
}
} catch (error) {
console.error("onLiveSummaryStoreChanged error:", error);
}
};
function bindEvent(liveID : string) : void {
getRTCRoomEngineManager().on("liveSummaryStoreChanged", onLiveSummaryStoreChanged, liveID);
}
export function useLiveSummaryState(liveID : string) {
bindEvent(liveID);
return {
summaryData, // 直播间统计信息
};
}
export default useLiveSummaryState;

View File

@@ -0,0 +1,146 @@
/**
* @module LoginState
* @module_description
* 用户身份认证与登录管理模块
* 核心功能:负责用户身份验证、登录状态管理、用户信息维护等基础认证服务。
* 技术特点:支持多种认证方式、会话管理、权限验证等高级功能,确保用户身份的安全和有效。
* 业务价值:为直播平台提供基础的用户认证能力,是所有其他业务模块的前置条件。
* 应用场景:用户登录、身份验证、会话管理、权限控制等基础认证场景。
*/
import { ref } from "vue";
import { UserProfileParam, LoginOptions, LogoutOptions, SetSelfInfoOptions } from "@/uni_modules/tuikit-atomic-x";
import { getRTCRoomEngineManager } from "./rtcRoomEngine";
import { callUTSFunction, safeJsonParse } from "../utils/utsUtils";
/**
* 当前登录用户信息
* @type {Ref<UserProfileParam>}
* @memberof module:LoginState
* @example
* import { useLoginState } from '@/uni_modules/tuikit-atomic-x/state/LoginState';
* const { loginUserInfo } = useLoginState();
*
* // 监听用户信息变化
* watch(loginUserInfo, (newUserInfo) => {
* if (newUserInfo) {
* console.log('用户信息更新:', newUserInfo);
* console.log('用户ID:', newUserInfo.userID);
* console.log('用户昵称:', newUserInfo.nickname);
* console.log('用户头像:', newUserInfo.avatarURL);
* }
* });
*
* // 获取当前用户信息
* const currentUser = loginUserInfo.value;
* if (currentUser) {
* console.log('当前登录用户:', currentUser.nickname);
* }
*/
const loginUserInfo = ref<UserProfileParam>();
/**
* 当前登录状态
* @type {Ref<string>}
* @memberof module:LoginState
* @example
* import { useLoginState } from '@/uni_modules/tuikit-atomic-x/state/LoginState';
* const { logout } = useLoginState();
* logout({
* onSuccess: () => console.log('登出成功'),
* onError: (error) => console.error('登出失败:', error)
* });
*/
const loginStatus = ref<string>();
/**
* 登录方法
* @param {LoginOptions} params - 登录参数
* @returns {void}
* @memberof module:LoginState
* @example
* import { useLoginState } from '@/uni_modules/tuikit-atomic-x/state/LoginState';
* const { login } = useLoginState();
* login({
* sdkAppID: 1400000000,
* userID: 'user123',
* userSig: 'eJx1kF1PwzAMhv9KlG...',
* onSuccess: () => console.log('登录成功'),
* onError: (error) => console.error('登录失败:', error)
* });
*/
function login(params: LoginOptions): void {
callUTSFunction("login", params);
}
/**
* 登出方法
* @param {LogoutOptions} [params] - 登出参数(可选)
* @returns {void}
* @memberof module:LoginState
* @example
* import { useLoginState } from '@/uni_modules/tuikit-atomic-x/state/LoginState';
* const { logout } = useLoginState();
* logout({
* onSuccess: () => console.log('登出成功'),
* onError: (error) => console.error('登出失败:', error)
* });
*/
function logout(params?: LogoutOptions): void {
callUTSFunction("logout", params || {});
}
/**
* 设置用户信息
* @param {SetSelfInfoOptions} userInfo - 用户信息
* @returns {void}
* @memberof module:LoginState
* @example
* import { useLoginState } from '@/uni_modules/tuikit-atomic-x/state/LoginState';
* const { setSelfInfo } = useLoginState();
* setSelfInfo({
* userID: 'user123',
* nickname: '张三',
* avatarURL: 'https://example.com/avatar.jpg',
* onSuccess: () => console.log('用户信息设置成功'),
* onError: (error) => console.error('用户信息设置失败:', error)
* });
*/
function setSelfInfo(userInfo: SetSelfInfoOptions): void {
callUTSFunction("setSelfInfo", userInfo);
}
function getLoginUserInfo(): UserProfileParam | undefined {
return loginUserInfo.value;
}
const onLoginStoreChanged = (eventName: string, res: string): void => {
try {
if (eventName === "loginUserInfo") {
const data = safeJsonParse<UserProfileParam>(res, {});
loginUserInfo.value = data;
} else if (eventName === "loginStatus") {
loginStatus.value = safeJsonParse<string>(res, "");
}
} catch (error) {
console.error("onLoginStoreChanged error:", error);
}
};
function bindEvent(): void {
getRTCRoomEngineManager().on("loginStoreChanged", onLoginStoreChanged, '');
}
export function useLoginState() {
bindEvent();
return {
loginUserInfo, // 当前登录用户信息
loginStatus, // 当前登录状态
login, // 登录方法
logout, // 登出方法
setSelfInfo, // 设置用户信息
getLoginUserInfo, // 获取登录用户信息
};
}
export default useLoginState;

View File

@@ -0,0 +1,11 @@
import { RTCRoomEngineManager } from "@/uni_modules/tuikit-atomic-x";
let instance : RTCRoomEngineManager | null = null;
//TODO: 这个文件的命名待讨论,或者直接干掉这个类?
export function getRTCRoomEngineManager() : RTCRoomEngineManager {
if (!instance) {
instance = new RTCRoomEngineManager();
}
return instance;
}