video
视频文件直接使用video标签预览,和后端设定的是学员在观看视频时,前端会5秒钟上传一次进度,记录学员当前视频所学的进度,当视频观看完成时会立即触发一次进度上报接口。
<videoref="video":src="xxxxx"class="h-full":class="{'videoids':xxxx}" // 有的视频不允许拖动进度条时加上这个classpreload="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 = trueif (this.progressObj.timer) returnthis.getStart()
},
pause() {this.progressObj.play = false
},
ended() {if (this.progressObj.timer) {clearTimeout(this.progressObj.timer)this.progressObj.timer = null}this.updateLearnProgress()
},
getStart() {const that = thisthis.progressObj.timer = setTimeout(() => {clearTimeout(that.progressObj.timer)that.progressObj.timer = nullthat.updateLearnProgress()}, 5000)
},
updateLearnProgress() {if (!this.$refs.video) returnconst 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库进行文件预览。在翻页时进行进度上传,对于频繁的滚动翻页会进行防抖处理。
<PDFPreviewProgressref="pdf":path="xxxx":info="showInfo"
/>// PDFPreviewProgress.vue
<template><div class="w-full h-full"><iframeid="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.PDFViewerApplicationif (!(PDFViewerApplication.pagesCount && PDFViewerApplication.pdfViewer)) return;clearInterval(this.interval)this.interval = nullthis.PDFViewerApplication = PDFViewerApplicationPDFViewerApplication.page = Math.max(1, this.info.currentProgress)const that = thisthis.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>