UNPKG

ps-tcplayer

Version:

Tencent Cloud Player component with Vue2/Vue3 compatibility

299 lines (250 loc) 9.02 kB
import memoryPlayHtml from './index.html' import './index.scss' import { parseDom } from '../../utils' /** * 记忆播放组件 */ export default class MemoryPlayComponent { /** * @constructor 记忆播放组件构造函数 */ constructor (player, autoPlay = false, getTime, saveTimeFunction, htime) { this.html = parseDom(memoryPlayHtml) this.player = player this.autoPlay = autoPlay this.getTime = getTime || this._getTime this.saveTimeFunction = saveTimeFunction || this._saveTime this.hasMemoryDisplay = false this.htime = htime || 0 this.memoryKey = 'tcplayer_memory_' } createEl (el) { el.appendChild(this.html) } ready () { try{ const player = this.player; let that = this let playerOptions = player.options_ || {} let memoryVideo = '' if (playerOptions.fileID) { memoryVideo = playerOptions.fileID } else if (playerOptions.src) { memoryVideo = playerOptions.src.replace(/\?.*$/, '') } this.memoryKey = 'tcplayer_memory_' + memoryVideo let memoryTime = 0 if (this.htime > 0) { memoryTime = this.htime } else { memoryTime = this.getTime(this.memoryKey) ? parseInt(this.getTime(this.memoryKey)) : 0 } this.hasMemoryDisplay = false var memoryVideoTime_cto, memoryVideoTime, lasttime, seektime memoryVideoTime = this.getVideoTime(memoryTime) memoryVideoTime_cto = this.getVideoTime(this.htime) if (!this.hasMemoryDisplay && memoryTime > 0) { this.hasMemoryDisplay = true let duration = 0 try { duration = player.duration() || 0 } catch (e) { console.error('获取视频时长失败:', e) } if (memoryTime <= parseInt(duration) - 2) { var memoryDomString = '' seektime = 0 lasttime = memoryVideoTime if (this.autoPlay) { memoryDomString = `<div class="memory-play"><span>您上次学习到${lasttime}已自动为您续播</span><span class="play-jump">从头播放</span><i class="iconfont icon-close"></i></div>` player.currentTime(memoryTime) } else { memoryDomString = `<div class="memory-play"><span>您上次学习到${lasttime}</span><span class="play-jump">继续播放</span><i class="iconfont icon-close"></i></div>` } if (player.paused()) { if(this.autoPlay) { // player.play() // try { // const originalVolume = player.volume(); // player.volume(0); // player.play().then(() => { // setTimeout(() => { // player.volume(originalVolume); // }, 500); // }).catch(err => { // console.warn('自动播放被阻止,需要用户手动播放:', err); // player.volume(originalVolume); // }); // } catch(err) { // console.warn('自动播放尝试失败:', err); // } } } this.html.innerHTML = memoryDomString let timeoutMemory = setTimeout(() => { this.html.innerHTML = '' }, 5000) var closebtn = this.html.querySelector('.icon-close') if(!!closebtn){ closebtn.onclick = () => { this.html.innerHTML = '' clearTimeout(timeoutMemory) } } var jumpbtn = this.html.querySelector('.play-jump') if(!!jumpbtn){ jumpbtn.onclick = () => { if (this.autoPlay) { player.currentTime(0) } else { player.currentTime(memoryTime) } if (player.paused() && this.autoPlay) { try { player.play().catch(err => { console.warn('点击后播放被阻止,这种情况很少见:', err); }); } catch(err) { console.warn('播放尝试失败:', err); } } this.html.innerHTML = '' clearTimeout(timeoutMemory) } } } } setTimeout(() => { if (!this.hasMemoryDisplay && memoryTime > 0) { this.processMemoryPlayPrompt(memoryTime); } }, 500); this.setupTimeSaving(); }catch(err){ console.error(err) } } error () { this.setMemory() } dispose () { this.setMemory() if (this.visibilityHandler) { document.removeEventListener('visibilitychange', this.visibilityHandler); } if (this.unloadHandler) { window.removeEventListener('beforeunload', this.unloadHandler); } if (this.progressInterval) { clearInterval(this.progressInterval); } } processMemoryPlayPrompt(memoryTime) { const player = this.player; this.hasMemoryDisplay = true let duration = 0 try { duration = player.duration() || 0 } catch (e) { console.error('获取视频时长失败:', e) } if (memoryTime <= parseInt(duration) - 2) { const formattedTime = this.getVideoTime(memoryTime); let memoryDomString = ''; if (this.autoPlay) { memoryDomString = `<div class="memory-play"><span>您上次学习到${formattedTime}已自动为您续播</span><span class="play-jump">从头播放</span><i class="iconfont icon-close"></i></div>`; player.currentTime(memoryTime); } else { memoryDomString = `<div class="memory-play"><span>您上次学习到${formattedTime}</span><span class="play-jump">继续播放</span><i class="iconfont icon-close"></i></div>`; } this.html.innerHTML = memoryDomString; let timeoutMemory = setTimeout(() => { this.html.innerHTML = ''; }, 5000); const closeBtn = this.html.querySelector('.icon-close'); if (closeBtn) { closeBtn.onclick = () => { this.html.innerHTML = ''; clearTimeout(timeoutMemory); }; } const jumpBtn = this.html.querySelector('.play-jump'); if (jumpBtn) { jumpBtn.onclick = () => { if (this.autoPlay) { player.currentTime(0); } else { player.currentTime(memoryTime); } if (player.paused()) { try { player.play().catch(err => { console.warn('点击后播放被阻止:', err); }); } catch(err) { console.warn('播放尝试失败:', err); } } this.html.innerHTML = ''; clearTimeout(timeoutMemory); }; } } } setupTimeSaving() { const player = this.player; let that = this; document.removeEventListener('visibilitychange', this.visibilityHandler); this.visibilityHandler = function() { if (document.visibilityState === 'hidden' && player.currentTime() > 0) { that.saveTimeFunction(that.memoryKey, player.currentTime()); } }; document.addEventListener('visibilitychange', this.visibilityHandler); window.removeEventListener('beforeunload', this.unloadHandler); this.unloadHandler = function() { if (player.currentTime() > 0) { that.saveTimeFunction(that.memoryKey, player.currentTime()); } }; window.addEventListener('beforeunload', this.unloadHandler); this.progressInterval = setInterval(() => { if (!player.paused() && player.currentTime() > 0) { that.saveTimeFunction(that.memoryKey, player.currentTime()); } }, 30000); // 每30秒保存一次 } setMemory () { const player = this.player; try{ if (!player || typeof player.currentTime !== 'function') { return; } const currentTime = player.currentTime(); if (currentTime > 0) { this.saveTimeFunction(this.memoryKey, currentTime); } }catch(err){ console.error('保存记忆时间失败:', err); } } getVideoTime(duration) { let secondTotal = Math.round(duration) let hour = Math.floor(secondTotal / 3600) let minute = Math.floor((secondTotal - hour * 3600) / 60) let second = secondTotal - hour * 3600 - minute * 60 if (minute < 10) { minute = '0' + minute } if (second < 10) { second = '0' + second } return hour === 0 ? minute + ':' + second : hour + ':' + minute + ':' + second } _getTime(memoryVideo){ return localStorage.getItem(memoryVideo) } _saveTime(memoryVideo,currentTime){ localStorage.setItem(memoryVideo, currentTime) } }