UNPKG

jiker-tcplayer

Version:

tcplayer in Jiker

197 lines (189 loc) 6.15 kB
function VideoEvent(player) { this.videoInstance = player this.listenVideo(); } VideoEvent.prototype.init = function init() { this.clearWatchTimer(); this.duration = 0; this.startPoint = 0; this.current = null; this.lastTimePoint = null; this.Timer = null; // 初始化记录数据 this.watching = []; // 正在观看 this.viewed = []; // 历史已观看 this.watchDuration = 0; // 观看时长 // 初始化播放器 this.callbackMap = new Map(); this.is_ended = false; }; // 事件监听,把事件类型与回调放在一个map对象里 VideoEvent.prototype.on = function on(type, callback) { this.callbackMap.set(type, callback); }; // 视频监听事件 VideoEvent.prototype.listenVideo = function listenVideo() { this.videoInstance.on('durationchange', () => { this.removeNodeByClassName('custom-viewed-bar'); this.removeNodeByClassName('custom-append-bar'); this.duration = this.videoInstance.duration(); }); this.videoInstance.on('ended', () => { this.is_ended = true; const onEnded = this.callbackMap.get('ended'); if (onEnded instanceof Function) { onEnded(this.is_ended); } }); this.videoInstance.on('ratechange', () => { const cb = this.callbackMap.get('ratechange'); if (cb instanceof Function) { // 获取当前播放倍数 // 暂不支持 // const rate = this.videoInstance.player().playbackRate(); const rate = 1; cb(rate); } }); this.videoInstance.on('play', () => { this.beginWatchTimer(); this.dealPlay(); }); this.videoInstance.on('timeupdate', () => { const durCurrent = this.videoInstance.currentTime(); if ( this.current && this.lastTimePoint !== null && Math.abs(durCurrent - this.lastTimePoint) > 2 ) { this.dealPause(); this.dealPlay(); this.lastTimePoint = durCurrent; return; } this.lastTimePoint = durCurrent; if (this.current) { this.current.style.setProperty( 'width', `${100 * ((durCurrent - this.startPoint) / this.duration)}%` ); } }); this.videoInstance.on('pause', () => { clearInterval(this.Timer); this.dealPause(); }); }; VideoEvent.prototype.dealPlay = function dealPlay() { this.startPoint = this.videoInstance.currentTime() - 0.5; if (this.startPoint < 0) this.startPoint = 0; if (!document.getElementById('tcplayer-video-player')) return; const video = document .getElementById('tcplayer-video-player') .getElementsByClassName('vjs-progress-holder')[0]; this.current = document.createElement('div'); this.current.className = 'custom-append-bar'; this.current.style.setProperty('left', `${100 * (this.startPoint / this.duration)}%`); this.current.style.setProperty('background-color', '#1764E8'); this.current.style.setProperty('height', '100%'); this.current.style.setProperty('position', 'absolute'); video.append(this.current); }; VideoEvent.prototype.dealPause = async function dealPause() { this.current = null; const pauseTime = this.lastTimePoint || this.videoInstance.currentTime(); if (this.startPoint < pauseTime) { const duration = this.watchDuration; this.clearWatchTimer(); await this.callbackMap.get('record')({ stopTime: pauseTime, duration, currentPoints: [this.startPoint, pauseTime] }); } }; // 清除观看计时 VideoEvent.prototype.clearWatchTimer = function clearWatchTimer() { clearInterval(this.Timer); this.watchDuration = 0; }; // 开始观看计时 VideoEvent.prototype.beginWatchTimer = function beginWatchTimer() { this.Timer = setInterval(() => { this.watchDuration += 1; }, 1000); }; VideoEvent.prototype.dealWatchingList = function dealWatchingList(viewed = [], watching = []) { const list = []; const arr = [...watching, ...viewed]; const getBlock = num => { let min = null; arr.forEach(item => { if (item[0] > num) { if (min === null) { min = item; } else if (item[0] < min[0]) { min = item; } } }); if (min !== null) { arr.forEach(item => { if (item[1] > min[1]) { if (item[0] <= min[1]) { // eslint-disable-next-line prefer-destructuring min[1] = item[1]; } } }); list.push(min); getBlock(min[1]); } }; getBlock(-1); return list; }; // 设置节点 VideoEvent.prototype.setViewedPoints = function setViewedPoints(duration, viewed) { if (!document.getElementById('tcplayer-video-player')) return; const a = document.getElementById('tcplayer-video-player').getElementsByClassName('vjs-progress-holder')[0]; viewed.forEach(arr => { const [start, end] = arr; const c = document.createElement('div'); // start/duration最大只能1 const p = start / duration; c.style.setProperty('left', `${(p > 1 ? 1 : p) * 100}%`); c.className = 'custom-viewed-bar'; const coloredWidth = ((end - start) / duration) * 100 > 100 ? 100 : ((end - start) / duration) * 100; c.style.setProperty('width', `${coloredWidth}%`); c.style.setProperty('background-color', '#FFCC00'); c.style.setProperty('height', '100%'); c.style.setProperty('position', 'absolute'); a.insertBefore(c, a.children[1]); }); }; // 移除节点 VideoEvent.prototype.removeNodeByClassName = function removeNodeByClassName(name) { const nodeList = document.getElementsByClassName(name); const { length } = nodeList; for (let i = length - 1; i >= 0; i -= 1) { nodeList[i].remove(); } }; // 设置视频上次播放时间 VideoEvent.prototype.setCurrentTime = function setCurrentTime(lastPlayPosition, viewed = []) { if (!this.videoInstance) { setTimeout(() => { this.setCurrentTime(lastPlayPosition); }, 500); } else { this.videoInstance.currentTime(lastPlayPosition); this.setViewedPoints(this.videoInstance.duration(), viewed); } }; VideoEvent.prototype.setDefaultPlaybackRate = function setDefaultPlaybackRate() { // 暂不支持 // this.videoInstance.defaultPlaybackRate(rate); }; export default VideoEvent;