最近在做一个项目,要求前端发送video的播放记录,后台保存对应的时间和状态,用户下次进入页面,根据对应的信息加载video。最开始请教了一下前辈,使用了定时器的方法,每隔一段时间向后台发送对应的观看进度,然后暂停、切换等状态也发送对应的请求,但是,最后发现,如果用户拉动进度条然后立即推出,可能导致无法记录,最后采用了自己的一个思路,暂时实现了效果,可能有许多地方存在问题。
想法如下,三个用户操作记录对应的信息
1:用户切换视频,记录上一个视频观看进度
2:用户关闭浏览器,记录视频观看进度
3:用户刷新浏览器,记录视频观看进度
切换视频时,直接调用对应的函数,在切换video地址之前,记录一次信息即可,如有执行顺序问题,可采用链式调用的方式,或者结合一些es6的语法。这里会有一个问题,页面初次加载时,也会有切换视频的操作,此时不需要记录播放进度,我这里是加了一个判断处理
if (document.getElementsByTagName('video')[0].currentTime) {
('记录对应的观看进度->加载对应的视频信息(地址,currentTim等) return')
}
('加载对应的视频信息(地址,currentTim等)')
然后是对应的浏览器事件记录信息,最开始采用的是beforeDestroy(),最查资料发现beforeDestroy,destroyed是在被vue 被销毁的时候才会触发,但是页面刷新并没有触发vue 的销毁,它仅仅是浏览器的主动行为.后面解决采用了beforeunload事件解决,当浏览器窗口关闭或者刷新时,会触发beforeunload事件
采用beforeunload事件,记录对应的视频信息,会发现获取不到对应的节点信息,最后自己采用了本地存储解决代码如下:
mounted() {
window.addEventListener('beforeunload', 对应函数记录信息)
let that = this
const vid = document.getElementsByTagName('video')[0]
/**
* 获取video播放总时长,用于判断当当前播放时间等于播放时长时,不发起请求
* 定时存储用户观看进度等信息
**/
vid.onloadedmetadata = function () {
that.allTime = vid.duration
this.recodrTime = setInterval(() => {
if (
document.getElementsByTagName('video')[0].currentTime &&
that.resourceId
) {
localStorage.setItem(
'videoParams',
JSON.stringify({
courseId:that.id,
resourceId: that.resourceId,
resourceTime:
document.getElementsByTagName('video')[0].currentTime
})
)
}
}, 1000)
}
/**
* video结束回调,记录当前视频的状态为已结束
**/
vid.addEventListener(
'ended',
function () {
//结束
对应函数记录信息
},
false
)
},
beforeDestroy() {
setTimeout(() => {
window.removeEventListener('beforeunload', 对应函数记录信息)
}, 1000)
clearInterval(this.recodrTime)
this.resourceTime = null
}
解决思路大致如上,因为beforeunload初次加载也会调用,我是在记录信息的函数里加了些许判断解决。可能还有许多地方存在问题。
前端小白,如有大佬有更好的处理方案,欢迎讨论~