video
视频文件直接使用video标签预览,和后端设定的是学员在观看视频时,前端会5秒钟上传一次进度,记录学员当前视频所学的进度,当视频观看完成时会立即触发一次进度上报接口。
javascript
<video
ref="video"
:src="xxxxx"
class="h-full"
:class="{'videoids':xxxx}" // 有的视频不允许拖动进度条时加上这个class
preload="auto"
controls
@loadeddata="loadeddata"
@play="play"
@pause="pause"
@timeupdate="timeupdate" // 这个事件中可以处理弹出不同时间点跳出的随堂练习题目
@ended="ended"
/>
loadeddata() {
// 视频总时长
this.progressObj.duration = this.$refs.video.duration
// 设置视频从哪里开始播放,是后端返回的观看到的进度
this.$refs.video.currentTime = this.showInfo.currentProgress
},
play() {
this.progressObj.play = true
if (this.progressObj.timer) return
this.getStart()
},
pause() {
this.progressObj.play = false
},
ended() {
if (this.progressObj.timer) {
clearTimeout(this.progressObj.timer)
this.progressObj.timer = null
}
this.updateLearnProgress()
},
getStart() {
const that = this
this.progressObj.timer = setTimeout(() => {
clearTimeout(that.progressObj.timer)
that.progressObj.timer = null
that.updateLearnProgress()
}, 5000)
},
updateLearnProgress() {
if (!this.$refs.video) return
const currentProgress = Math.floor(this.$refs.video.currentTime)
api.xxx({
currentProgress: currentProgress,
......
}).then(({ data }) => {
if (this.$refs.video) { ...... }
})
if (this.progressObj.play) this.getStart()
},
<style scoped lang="scss">
.videoids::-webkit-media-controls-timeline {
display: none;
}
</style>
pdf/word/excel等文件,后端会统一处理返回pdf文件格式,前端使用pdfjs库进行文件预览。在翻页时进行进度上传,对于频繁的滚动翻页会进行防抖处理。
javascript
<PDFPreviewProgress
ref="pdf"
:path="xxxx"
:info="showInfo"
/>
// PDFPreviewProgress.vue
<template>
<div class="w-full h-full">
<iframe
id="prf-pre-pro"
:src="pdfurl"
width="100%"
height="100%"
/>
</div>
</template>
<script>
import { debounce } from 'lodash'
export default {
props: {
path: { type: String, default: '' },
info: { type:Object, default:() => ({}) },
},
data() {
return {
pdfurl: '',
interval: null,
}
},
watch: {
path() {
this.queryFile()
if (this.interval) {
clearInterval(this.interval)
this.interval = null
}
this.interval = setInterval(this.checkPdf, 300)
}
},
beforeDestroy() {
if (this.PDFViewerApplication) {
this.PDFViewerApplication.pdfViewer.eventBus.off('pagechanging', that.pageChange);
this.PDFViewerApplication = null
}
if (this.interval) {
clearInterval(this.interval)
this.interval = null
}
},
methods: {
queryFile() {
const fileUrl = '/xxxx/pdfjs/web/viewer.html'
this.pdfurl = fileUrl + '?file=' + encodeURIComponent(this.path)
},
checkPdf() {
if (!(document.getElementById('prf-pre-pro')?.contentWindow?.PDFViewerApplication)) return;
let PDFViewerApplication = document.getElementById('prf-pre-pro').contentWindow.PDFViewerApplication
if (!(PDFViewerApplication.pagesCount && PDFViewerApplication.pdfViewer)) return;
clearInterval(this.interval)
this.interval = null
this.PDFViewerApplication = PDFViewerApplication
PDFViewerApplication.page = Math.max(1, this.info.currentProgress)
const that = this
this.PDFViewerApplication.pdfViewer.eventBus.on('pagechanging', that.pageChange);
},
pageChange(evt) {
this.isUPdataProgress(evt.pageNumber, this.PDFViewerApplication.pagesCount)
},
isUPdataProgress: debounce(function(pageNum, pagesCount) {
this.$emit('updatePdfProgress', pageNum, pagesCount)
}, 1000)
}
}
</script>