ps-tcplayer
Version:
Tencent Cloud Player component with Vue2/Vue3 compatibility
299 lines (250 loc) • 9.02 kB
JavaScript
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)
}
}