UNPKG

cloudhub-playback-sdk

Version:

CloudHubPlaybackSDK

257 lines (256 loc) 13.6 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const ActionFactory_1 = __importDefault(require("../actions/ActionFactory")); const ActionEvent_1 = __importDefault(require("../ActionEvent")); const utils_1 = __importDefault(require("../helper/utils")); const UserController_1 = __importDefault(require("./UserController")); const Logger_1 = __importDefault(require("../Logger")); const RoomController_1 = __importDefault(require("./RoomController")); const RemoteVideoStateChangedAction_1 = __importDefault(require("../actions/RemoteVideoStateChangedAction")); const RemoteAudioStateChangedAction_1 = __importDefault(require("../actions/RemoteAudioStateChangedAction")); const MediaStateChangeAction_1 = __importDefault(require("../actions/MediaStateChangeAction")); const RemoteMultiAudioStateChangedAction_1 = __importDefault(require("../actions/RemoteMultiAudioStateChangedAction")); class PlaybackPlayerController { constructor(recordManager, options = {}) { if (!recordManager) { Logger_1.default.error('recordManager is required'); } this.recordManager = recordManager; this.currIndex = 0; //当前轮询的下标 this.time = null; //当前轮询的时间戳 this.actionTimer = null; //action定时器 this.options = this._defaultOptions(options); this.timeDifference = 0; //系统时间与 record 开始时间的差值 this.cacheAudioAction = null; this.cacheVideoAction = null; this.handleDelUserLeave = {}; } _defaultOptions(options = {}) { let defaultOptions = { timeStep: 1000, speed: 1 }; for (let key in options) { defaultOptions[key] = options[key]; } return defaultOptions; } start() { this.setTimeDifference(0); //初始化 系统时间与 record 开始时间的差值 //开启定时器 this.actionTimer = setInterval(() => { const curTime = new Date().getTime(); //获取系统时间 this.time = curTime - this.timeDifference; //获取这一次轮询的时间戳 //返回这一次时间戳内的所有 action 事件 默认1s轮询一次 如果设置快进 就根据快进的进度 const { index, actions } = this.recordManager.getActions(this.currIndex, this.time); this.currIndex = index; // 循环所有的事件 actions.forEach((action) => { //派发前处理 this.beforeAction(action); const actionObject = ActionFactory_1.default.create(action); /************需要注意的是在派发前处理还是派发后处理************/ //todo 派发事件 ActionEvent_1.default.dispatch(actionObject); }); }, this.options.timeStep / this.options.speed); } setTimeDifference(time = 0) { Logger_1.default.info('setTimeDifference', time); //time为0的话 回放时间轴回到初始状态 if (time === 0) { this.currIndex = 0; } const date = new Date(); const startTime = this.recordManager.getStartTime(); //回放开始时间 const endTime = this.recordManager.getEndTime(); //回放结束时间 const nextTime = date.getTime() - (startTime + time); //当前时间与回放开始时间计算出来的差值 if (nextTime <= endTime) { //快进的时间在合理范围内就赋值 this.timeDifference = nextTime; this.seekVideoPosition(nextTime); Logger_1.default.info('setTimeDifference success', date.getTime() - this.timeDifference); } else { //快进时间不合理 赋值为初始时间 this.timeDifference = date.getTime() - startTime; Logger_1.default.warning('setTimeDifference fail', this.timeDifference); } } seekVideoPosition(actionTs) { const date = new Date(); const time = date.getTime() - this.timeDifference; //快进的时间戳如果大于当前action的时间戳 就把视频的进度切换至发送action的时间点(发布视频时记录了发布时间戳) if (actionTs <= time) { const users = RoomController_1.default.getUsers(); for (let i = 0; i < users.length; i++) { const user = users[i]; if (user) { user.setAllVideoTime(actionTs); } } } } beforeAction(action) { const { method, ts } = action; //存储加入的用户 if (method === 'join') { const { properties, userName: uid } = action; properties.id = uid; RoomController_1.default.setUser(new UserController_1.default(properties)); } if (method === 'PubMsg' && action.data && action.data.name === 'SyncProperty') { const properties = Object.assign({}, action.data.data.user); RoomController_1.default.setUser(new UserController_1.default(properties)); } // 删除离开的用户 if (method === 'LEAVE') { const { username: uid } = action; const leaveUser = RoomController_1.default.getUser(uid); if (leaveUser && leaveUser.streams) { Object.values(leaveUser.streams).map((key) => { Object.values(key).map((item) => { const { options, streamId } = item; const mediaType = leaveUser.getStreamType(streamId); const customize = { streamId, method: 'cancelPublisher', userName: uid, }; if (this.handleDelUserLeave[streamId] === true && mediaType !== 'multiAudio') { const actionObject = new RemoteVideoStateChangedAction_1.default(Object.assign(customize, { options }), RoomController_1.default); ActionEvent_1.default.dispatch(actionObject); } if (this.handleDelUserLeave[streamId] === true && mediaType === 'multiAudio') { const actionMultiAudioObject = new RemoteMultiAudioStateChangedAction_1.default(Object.assign(customize, { options }), RoomController_1.default); ActionEvent_1.default.dispatch(actionMultiAudioObject, 'multiStream'); } }); }); } RoomController_1.default.delUser(uid); } // 音频改变,储存起来 if (method === 'updateStreamAttributes') { if (action.msg && action.msg.attrs && utils_1.default.hasKey(action.msg.attrs, 'mute_audio')) { this.cacheAudioAction = action; const _user = RoomController_1.default.getUserByStreamId(this.cacheAudioAction.streamId); if (_user) { const cacheAudioActionObject = new RemoteAudioStateChangedAction_1.default(Object.assign(this.cacheAudioAction, { userName: _user.id }), RoomController_1.default); ActionEvent_1.default.dispatch(cacheAudioActionObject, 'updateStreamAttributes'); this.cacheAudioAction = null; } } if (action.msg && action.msg.attrs && utils_1.default.hasKey(action.msg.attrs, 'mute_video')) { this.cacheVideoAction = action; const _user = RoomController_1.default.getUserByStreamId(this.cacheVideoAction.streamId); if (_user) { const mediaType = _user.getStreamType(this.cacheVideoAction.streamId); if (mediaType !== 'multiAudio') { const { options } = _user.getStreamByStreamId(this.cacheVideoAction.streamId); const cacheVideoActionObject = new RemoteVideoStateChangedAction_1.default(Object.assign(this.cacheVideoAction, { userName: _user.id, options }), RoomController_1.default); ActionEvent_1.default.dispatch(cacheVideoActionObject, 'updateStreamAttributes'); this.cacheVideoAction = null; } } } } //发布流时 存储当前用户的流 if (method === 'newPublisher') { const { userName: uid, streamId, options, filename, ts } = action; let { type } = options.attributes || {}; const user = RoomController_1.default.getUser(uid); const isMultiAudio = options && options.extensionId && options.extensionId.includes('audio'); type = isMultiAudio ? 'multiAudio' : type; if (!user) { return false; } const property = { streamId, filename, publishTime: ts, type, uid, options, }; user.setStream(type, property, () => { if (!this.handleDelUserLeave[streamId]) { this.handleDelUserLeave[streamId] = true; } const actionAudioObject = new RemoteAudioStateChangedAction_1.default(action, RoomController_1.default); if (actionAudioObject && actionAudioObject.options && actionAudioObject.options.attributes && utils_1.default.hasKey(actionAudioObject.options.attributes, 'mute_audio')) { ActionEvent_1.default.dispatch(actionAudioObject); } if (isMultiAudio) { const actionMultiAudioObject = new RemoteMultiAudioStateChangedAction_1.default(action, RoomController_1.default); ActionEvent_1.default.dispatch(actionMultiAudioObject, 'multiStream'); return; } const actionObject = new RemoteVideoStateChangedAction_1.default(action, RoomController_1.default); ActionEvent_1.default.dispatch(actionObject); if (this.cacheAudioAction) { const _user = RoomController_1.default.getUserByStreamId(this.cacheAudioAction.streamId); if (_user) { const cacheAudioActionObject = new RemoteAudioStateChangedAction_1.default(Object.assign(this.cacheAudioAction, { userName: _user.id }), RoomController_1.default); ActionEvent_1.default.dispatch(cacheAudioActionObject, 'updateStreamAttributes'); this.cacheAudioAction = null; } } if (this.cacheVideoAction) { const _user = RoomController_1.default.getUserByStreamId(this.cacheVideoAction.streamId); if (_user) { const mediaType = _user.getStreamType(this.cacheVideoAction.streamId); if (mediaType !== 'multiAudio') { const { options } = _user.getStreamByStreamId(this.cacheVideoAction.streamId); const cacheVideoActionObject = new RemoteVideoStateChangedAction_1.default(Object.assign(this.cacheVideoAction, { userName: _user.id, options }), RoomController_1.default); ActionEvent_1.default.dispatch(cacheVideoActionObject, 'updateStreamAttributes'); this.cacheVideoAction = null; } } } }); user.setVideoTime(ts, streamId); } // 媒体进度控制 if (method === 'controlmedia') { const { cmd, streamId } = action; const _user = RoomController_1.default.getUserByStreamId(streamId); const stream = _user.getStreamByStreamId(streamId); const mediaData = { attributes: stream.options.attributes, cmd, options: stream.options, streamId }; const actionObject = new MediaStateChangeAction_1.default(mediaData, RoomController_1.default); ActionEvent_1.default.dispatch(actionObject); } //取消流时 删除当前用户的流 if (method === 'cancelPublisher') { const { userName: uid, streamId } = action; const user = RoomController_1.default.getUserByStreamId(streamId); if (!user) { return false; } if (this.handleDelUserLeave[streamId]) { this.handleDelUserLeave[streamId] = false; } user.delStream(streamId); const type = user.getStreamType(streamId); if (type === 'multiAudio') { const actionMultiAudioObject = new RemoteMultiAudioStateChangedAction_1.default(action, RoomController_1.default); ActionEvent_1.default.dispatch(actionMultiAudioObject, 'multiStream'); } } // 判断是否结束 if (method === 'close') { Logger_1.default.info('回放已全部播放完成'); clearInterval(this.actionTimer); window.CloudHubPlayer.playFinished('Player is stop'); } } } exports.default = PlaybackPlayerController;