UNPKG

@tencentcloud/roomkit-web-vue3

Version:

<h1 align="center"> TUIRoomKit</h1> Conference (TUIRoomKit) is a product suitable for multi-person audio and video conversation scenarios such as business meetings, webinars, and online education. By integrating this product, you can add room management,

290 lines (289 loc) 11.3 kB
var __defProp = Object.defineProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); import TUIRoomEngine__default, { TUIVideoStreamType, TRTCVideoStreamType, TRTCVideoFillMode, TRTCVideoRotation, TRTCVideoMirrorType, TUIChangeReason, TUIRoomEvents } from "@tencentcloud/tuiroom-engine-js"; import { EventType } from "../types.mjs"; import { isMobile } from "../../utils/environment.mjs"; import { MESSAGE_DURATION } from "../../constants/message.mjs"; import logger from "../../utils/common/logger/index.mjs"; var StreamPlayMode = /* @__PURE__ */ ((StreamPlayMode2) => { StreamPlayMode2["PLAY"] = "play"; StreamPlayMode2["STOP"] = "stop"; StreamPlayMode2["PLAY_IN_VISIBLE"] = "playInVisible"; return StreamPlayMode2; })(StreamPlayMode || {}); var StreamPlayQuality = /* @__PURE__ */ ((StreamPlayQuality2) => { StreamPlayQuality2["HIGH"] = "high"; StreamPlayQuality2["LOW"] = "low"; StreamPlayQuality2["Default"] = "default"; return StreamPlayQuality2; })(StreamPlayQuality || {}); class MediaManager { constructor(service) { __publicField(this, "service"); __publicField(this, "intersectionObserver", null); __publicField(this, "observerDataMap", /* @__PURE__ */ new Map()); __publicField(this, "observerRoot", null); __publicField(this, "onUserVideoStateChanged", (eventInfo) => { const { userId, streamType, hasVideo, reason } = eventInfo; if (userId === this.service.basicStore.userId && !hasVideo && reason === TUIChangeReason.kChangedByAdmin) { if (streamType === TUIVideoStreamType.kCameraStream) { this.service.emit(EventType.ROOM_NOTICE_MESSAGE, { type: "warning", message: this.service.t("Your camera has been turned off"), duration: MESSAGE_DURATION.NORMAL }); } if (streamType === TUIVideoStreamType.kScreenStream) { this.service.emit(EventType.ROOM_NOTICE_MESSAGE_BOX, { title: this.service.t("Your screen sharing has been stopped"), message: this.service.t( "Your screen sharing has been stopped, Now only the host/admin can share the screen" ), confirmButtonText: this.service.t("I got it") }); } } }); this.service = service; this.bindRoomEngineEvents(); } async startPlayVideo(options) { var _a, _b, _c; const { userId, streamType, view, observerViewInVisible } = options; logger.info( "MediaManager.startPlayVideo", userId, streamType, view, observerViewInVisible ); const streamInfo = this.service.roomStore.getStreamInfo(userId, streamType); if (!streamInfo) { return; } (_a = streamInfo.playDomMap) == null ? void 0 : _a.set(view, streamType); if (!observerViewInVisible) { await this.doStartPlayVideo({ userId, streamType }); return; } this.initIntersectionObserver(); this.observerDataMap.set( view, Object.assign(this.observerDataMap.get(view) || {}, { userId, streamType }) ); (_b = this.intersectionObserver) == null ? void 0 : _b.observe(view); if ((_c = this.observerDataMap.get(view)) == null ? void 0 : _c.isIntersection) { await this.doStartPlayVideo({ userId, streamType }); } } // If only one view wants to stop playing, update the viewList, but don't stop the stream. // If no view is passed in, the stream is stopped. async stopPlayVideo(options) { var _a; const { userId, streamType, view } = options; logger.info("MediaManager.stopPlayVideo", userId, streamType, view); const streamInfo = this.service.roomStore.getStreamInfo(userId, streamType); if (!(streamInfo == null ? void 0 : streamInfo.playDomMap) || (streamInfo == null ? void 0 : streamInfo.playDomMap.size) === 0) { return; } if (this.observerDataMap.get(view)) { this.observerDataMap.delete(view); (_a = this.intersectionObserver) == null ? void 0 : _a.unobserve(view); } streamInfo == null ? void 0 : streamInfo.playDomMap.delete(view); if ((streamInfo == null ? void 0 : streamInfo.playDomMap.size) > 0) { await this.doStartPlayVideo({ userId, streamType }); } else { await this.doStopPlayVideo(options); } } initIntersectionObserver() { if (!this.intersectionObserver || document.getElementById("roomContainer") !== this.observerRoot) { const observerRoot = document.getElementById("roomContainer"); this.intersectionObserver = new IntersectionObserver( this.intersectionObserverCallback.bind(this), { root: observerRoot, rootMargin: "0px" } ); this.observerDataMap = /* @__PURE__ */ new Map(); this.observerRoot = observerRoot; } } intersectionObserverCallback(entries) { entries.forEach((entry) => { var _a; const { isIntersecting, target } = entry; const observerData = this.observerDataMap.get(target); if (!observerData) { return; } const { userId, streamType } = observerData; const streamInfo = this.service.roomStore.getStreamInfo( userId, streamType ); if (!streamInfo) { return; } if (isIntersecting) { observerData.isIntersection = true; if ((streamInfo == null ? void 0 : streamInfo.playDomMap) && (streamInfo == null ? void 0 : streamInfo.playDomMap.size) > 0) { this.doStartPlayVideo({ userId, streamType }); } } else { observerData.isIntersection = false; const isContinuePlay = Array.from( ((_a = streamInfo == null ? void 0 : streamInfo.playDomMap) == null ? void 0 : _a.keys()) || [] ).find( (item) => { var _a2; return !this.observerDataMap.get(item) || ((_a2 = this.observerDataMap.get(item)) == null ? void 0 : _a2.isIntersection); } ); if (!isContinuePlay) { this.doStopPlayVideo({ userId, streamType }); } } }); } getPlayStreamType(userId, streamType) { var _a; if (streamType === TUIVideoStreamType.kScreenStream) { return streamType; } const streamInfo = this.service.roomStore.getStreamInfo(userId, streamType); if ((streamInfo == null ? void 0 : streamInfo.playDomMap) && (streamInfo == null ? void 0 : streamInfo.playDomMap.size) > 0) { const playStreamTypeList = Array.from((_a = streamInfo == null ? void 0 : streamInfo.playDomMap) == null ? void 0 : _a.values()); if (playStreamTypeList.includes(TUIVideoStreamType.kCameraStream)) { return TUIVideoStreamType.kCameraStream; } return TUIVideoStreamType.kCameraStreamLow; } return streamType; } async doStartPlayVideo(options) { var _a, _b, _c; const { userId, streamType } = options; const streamInfo = this.service.roomStore.getStreamInfo(userId, streamType); if (!streamInfo) { return; } const playStreamType = this.getPlayStreamType(userId, streamType); const viewIdList = Array.from(streamInfo.playDomMap.keys()).map((item) => { if (item instanceof HTMLElement) { return item == null ? void 0 : item.id; } return item; }); this.service.roomStore.updateStreamInfo({ userId, streamType, isLoading: true }); if (userId === this.service.basicStore.userId && streamType === TUIVideoStreamType.kCameraStream) { (_a = this.service.roomEngine.instance) == null ? void 0 : _a.setLocalVideoView({ view: viewIdList }); } else { (_b = this.service.roomEngine.instance) == null ? void 0 : _b.setRemoteVideoView({ userId, streamType: playStreamType, view: viewIdList }); await this.setVideoRenderParams({ userId, streamType }); await ((_c = this.service.roomEngine.instance) == null ? void 0 : _c.startPlayRemoteVideo({ userId, streamType: playStreamType })); } this.service.roomStore.updateStreamInfo({ userId, streamType, isLoading: false }); } async setVideoRenderParams(options) { var _a; const { userId, streamType } = options; if (userId !== this.service.basicStore.userId) { const trtcCloud = (_a = this.service.roomEngine.instance) == null ? void 0 : _a.getTRTCCloud(); const trtcStreamType = streamType === TUIVideoStreamType.kScreenStream ? TRTCVideoStreamType.TRTCVideoStreamTypeSub : TRTCVideoStreamType.TRTCVideoStreamTypeBig; let trtcFillMode = TRTCVideoFillMode.TRTCVideoFillMode_Fit; if (isMobile && streamType !== TUIVideoStreamType.kScreenStream) { trtcFillMode = TRTCVideoFillMode.TRTCVideoFillMode_Fill; } await (trtcCloud == null ? void 0 : trtcCloud.setRemoteRenderParams(userId, trtcStreamType, { mirrorType: TRTCVideoMirrorType.TRTCVideoMirrorType_Disable, rotation: TRTCVideoRotation.TRTCVideoRotation0, fillMode: trtcFillMode })); } } async doStopPlayVideo(options) { var _a, _b; const { userId, streamType } = options; this.service.roomStore.updateStreamInfo({ userId, streamType, isLoading: false }); if (userId === this.service.basicStore.userId && streamType === TUIVideoStreamType.kCameraStream) { (_a = this.service.roomEngine.instance) == null ? void 0 : _a.setLocalVideoView({ view: null }); } else { await ((_b = this.service.roomEngine.instance) == null ? void 0 : _b.stopPlayRemoteVideo({ userId, streamType })); } } onUserAudioStateChanged(eventInfo) { const { userId, hasAudio, reason } = eventInfo; if (userId === this.service.basicStore.userId && !hasAudio && reason === TUIChangeReason.kChangedByAdmin) { this.service.emit(EventType.ROOM_NOTICE_MESSAGE, { type: "warning", message: this.service.t("Your microphone has been turned off"), duration: MESSAGE_DURATION.NORMAL }); } } dispose() { this.intersectionObserver = null; this.observerDataMap = /* @__PURE__ */ new Map(); } bindRoomEngineEvents() { TUIRoomEngine__default.once("ready", () => { var _a, _b; (_a = this.service.roomEngine.instance) == null ? void 0 : _a.on( TUIRoomEvents.onUserVideoStateChanged, this.onUserVideoStateChanged.bind(this) ); (_b = this.service.roomEngine.instance) == null ? void 0 : _b.on( TUIRoomEvents.onUserAudioStateChanged, this.onUserAudioStateChanged.bind(this) ); }); } unbindRoomEngineEvents() { var _a, _b; (_a = this.service.roomEngine.instance) == null ? void 0 : _a.off( TUIRoomEvents.onUserVideoStateChanged, this.onUserVideoStateChanged ); (_b = this.service.roomEngine.instance) == null ? void 0 : _b.off( TUIRoomEvents.onUserAudioStateChanged, this.onUserAudioStateChanged ); } } export { MediaManager, StreamPlayMode, StreamPlayQuality };