import TRTC from 'trtc-sdk-v5' import { useNotification } from 'naive-ui' import { ref } from 'vue' import userData from '@/utils/userdata' interface RoomOption { userId: string, roomId: number, sdkAppId: number, userSig: string } export interface UserList { userName: string, userId: number, isMute: boolean, // 是否静音 isVideo: boolean, // 是否有视频 isState: boolean, // 是否到场 manageId: number, type: boolean, orgName: string, isCreate: number, isMe: boolean } class meetingService { private trtc: any = null private notification = useNotification() public list = ref([] as UserList[]) private loginInfo = userData.getUserData().loginInfo // 监测设备 private async detectionDevice() { let status = true const micList = await TRTC.getMicrophoneList() const speakerList = await TRTC.getSpeakerList() const hasMicrophoneDevice = micList.length > 0 const hasSpeakerDevice = speakerList.length > 0 if (!hasMicrophoneDevice || !hasSpeakerDevice) { status = false } if (hasMicrophoneDevice) { try { await this.trtc.startLocalAudio({ publish: false }) await this.trtc.enableAudioVolumeEvaluation(250) await this.trtc.stopLocalAudio() } catch (error) { status = false } } return status } // 加入房间+发布local video|audio public async joinRoom(options: RoomOption, videoDomID: string) { if (!this.trtc) return await this.trtc.enterRoom(options) this.isStartLocalVideo(false, videoDomID) this.isStartLocalAuido(false) const { userId } = options this.list.value.forEach((el) => { if (+userId === el.userId) { el.isState = true el.isMute = false el.isVideo = false } }) } // 退出房间 public async exitRoom() { if (!this.trtc) return await this.trtc.exitRoom() await this.trtc.stopLocalVideo() await this.trtc.stopLocalAudio() this.destroy() } // 是否静音远程用户 public async isStartRomoteAudio(userId: string, mute: boolean) { if (!this.trtc) return await this.trtc.muteRemoteAudio(userId, mute) } // 是否本地视频推送 public async isStartLocalVideo(mute: boolean, videoDomID: string) { if (!this.trtc) return if (mute) await this.trtc.stopLocalVideo() if (!mute) await this.trtc.startLocalVideo({ view: document.getElementById(videoDomID) }) } // 是否本地音频推送 public async isStartLocalAuido(mute: boolean) { if (!this.trtc) return if (mute) await this.trtc.stopLocalAudio() if (!mute) await this.trtc.startLocalAudio() } // 设置参会人员 public setUserList(userList: UserList[]) { // 找出自己 const arr = [] for (let k = 0; k < userList.length; k++) { const el = userList[k] if (el.isCreate) { arr.unshift({ ...el, isMute: true, isVideo: true, isState: false, isMe: this.loginInfo.userId === el.userId, type: !!el.isCreate }) } else { arr.push({ ...el, isMute: true, isVideo: true, isState: false, isMe: this.loginInfo.userId === el.userId, type: !!el.isCreate }) } } console.log('参会人员', arr) this.list.value = arr } // 初始化 public async _init() { if (this.trtc) this.destroy() // creta this.trtc = TRTC.create() // 检测设备 const status = await this.detectionDevice() if (!status) this.notification.error({ content: '请检查你的麦克风或扬声器是否正常' }) // 监听房间事件 this.trtc.on(TRTC.EVENT.ERROR, this.handleError.bind(this)) // this.trtc.on(TRTC.EVENT.KICKED_OUT, this.handleKickedOut.bind(this)) this.trtc.on(TRTC.EVENT.REMOTE_USER_ENTER, this.handleRemoteUserEnter.bind(this)) this.trtc.on(TRTC.EVENT.REMOTE_USER_EXIT, this.handleRemoteUserExit.bind(this)) this.trtc.on(TRTC.EVENT.REMOTE_AUDIO_UNAVAILABLE, this.handleRemoteAudioUnavailable.bind(this)) this.trtc.on(TRTC.EVENT.REMOTE_AUDIO_AVAILABLE, this.handleRemoteAudioAvailable.bind(this)) this.trtc.on(TRTC.EVENT.REMOTE_VIDEO_AVAILABLE, this.handleRemoteVideoAvailable.bind(this)) this.trtc.on(TRTC.EVENT.REMOTE_VIDEO_UNAVAILABLE, this.handleRemoteVideoUnavailable.bind(this)) // this.trtc.on(TRTC.EVENT.AUDIO_VOLUME, this.handleAudioVolume.bind(this)) return true } // 错误信息 private handleError(error: { message: string }) { this.notification.error({ content: error.message, duration: 2000 }) } // 远程用户加入 private handleRemoteUserEnter(event: { userId: string }) { console.log('远程用户加入', event) const { userId } = event this.list.value.forEach((el) => { if (+userId === el.userId) { el.isState = true } }) } // 远程用户离开 private handleRemoteUserExit(event: { userId: string }) { console.log('远程用户离开', event) const { userId } = event this.list.value.forEach((el) => { if (+userId === el.userId) { el.isState = false el.isMute = true el.isVideo = true } }) } // 远程用户音频不可用 private handleRemoteAudioUnavailable(event: { userId: string }) { console.log('远程用户音频不可用', event) const { userId } = event this.list.value.forEach((el) => { if (+userId === el.userId) { el.isMute = true } }) } // 远程用户音频可用 private handleRemoteAudioAvailable(event: { userId: string }) { console.log('远程用户音频可用', event) const { userId } = event this.list.value.forEach((el) => { if (+userId === el.userId) { el.isMute = false } }) } // 远程用户视频不可用 private handleRemoteVideoUnavailable(event: { userId: string; streamType: string }) { console.log('远程用户视频不可用', event) const { userId, streamType } = event this.trtc.updateRemoteVideo({ userId, streamType, view: `D-${userId}` }) this.list.value.forEach((el) => { if (+userId === el.userId) { el.isVideo = true } }) } // 远程用户视频可用 private handleRemoteVideoAvailable(event: { userId: string; streamType: string }) { console.log('远程用户视频可用', event) const { userId, streamType } = event this.trtc.startRemoteVideo({ userId, streamType, view: `D-${userId}` }) this.list.value.forEach((el) => { if (+userId === el.userId) { el.isVideo = false } }) } private destroy() { if (this.trtc) this.trtc.destroy() this.trtc = null } } export default meetingService