|
|
@@ -55,22 +55,31 @@
|
|
|
style="height: 900px; width: 100%; background-color: #000"
|
|
|
ref="videoRef"
|
|
|
controls
|
|
|
- Controlslist="nodownload noplaybackrate"
|
|
|
+ Controlslist="nodownload noplaybackrate noremoteplayback disablePictureInPicture"
|
|
|
+ @timeupdate="timeUpdate"
|
|
|
+ :currentTime="currentTimenew"
|
|
|
>
|
|
|
<source :src="videoUrl" type="video/mp4" />
|
|
|
<source :src="videoUrl" type="video/ogg" />
|
|
|
您的浏览器不支持 HTML5 video 标签。
|
|
|
</video>
|
|
|
- <rightMenu :idsObj="idsObj" :dataList="classTimeData" ref="rightNenuRef"></rightMenu>
|
|
|
+ <rightMenu :idsObj="idsObj" :dataList="classTimeData" ref="rightNenuRef" @videoSpeed="videoSpeed"></rightMenu>
|
|
|
</a-card>
|
|
|
<a-card :bordered="false" class="mt-2">
|
|
|
<a-tabs v-model:activeKey="tabsActiveKey">
|
|
|
<a-tab-pane key="1" tab="讲义">
|
|
|
- <div style="height: 500px">
|
|
|
+ <div style="height: 900px">
|
|
|
<vue-office-pdf :src="itemObj.url" style="width: 100%; height: 100%" />
|
|
|
</div>
|
|
|
</a-tab-pane>
|
|
|
- <a-tab-pane key="2" tab="字幕">字幕</a-tab-pane>
|
|
|
+ <a-tab-pane key="2" tab="字幕">
|
|
|
+ <div style="height: 900px; overflow-y: auto">
|
|
|
+ <div v-for="(item, idx) in danmuObj.srtInfoList" :key="idx">
|
|
|
+ <div>{{ item.startTime }}~{{ item.endTime }}</div>
|
|
|
+ <div style="cursor: pointer; padding: 10px 0" @click="videoSpeed(item)">{{ item.text }}</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </a-tab-pane>
|
|
|
<a-tab-pane key="3" tab="笔记">
|
|
|
<note :idsObj="idsObj" ref="noteRef" @edit="noteEdit"></note>
|
|
|
</a-tab-pane>
|
|
|
@@ -92,7 +101,7 @@
|
|
|
import note from './note.vue'
|
|
|
import askDiv from './ask.vue'
|
|
|
import VueOfficePdf from '@vue-office/pdf'
|
|
|
-
|
|
|
+ import axios from 'axios'
|
|
|
const route = useRoute()
|
|
|
const router = useRouter()
|
|
|
const classDetail = ref({})
|
|
|
@@ -102,6 +111,7 @@
|
|
|
const selectedKeys = ref([])
|
|
|
const collapsed = ref(false)
|
|
|
const videoRef = ref()
|
|
|
+ const currentTimenew = ref()
|
|
|
const idsObj = computed(() => {
|
|
|
let item = findNodeByKey(classTimeList.value, selectedKeys.value[0])
|
|
|
return {
|
|
|
@@ -152,7 +162,64 @@
|
|
|
let item = classTimeData.value.length > 0 ? classTimeData.value.filter((r) => r.funcType == 2)[0] : { url: '' }
|
|
|
return item
|
|
|
})
|
|
|
+ const danmuObj = computed(() => {
|
|
|
+ let item = classTimeData.value.length > 0 ? classTimeData.value.filter((r) => r.funcType == 3)[0] : { url: '' }
|
|
|
+ console.log('🚀 ~ item:', item)
|
|
|
+ if (item?.url) {
|
|
|
+ GetSrtInfo(item.url)
|
|
|
+ }
|
|
|
+ return item
|
|
|
+ })
|
|
|
const videoUrl = ''
|
|
|
+ const newsschedule = ref(0)
|
|
|
+ const currTime = ref(null)
|
|
|
+ const maxTime = ref(0)
|
|
|
+ const initialtime = ref(0)
|
|
|
+ const videoContext = ref()
|
|
|
+ const timeStamp1 = ref()
|
|
|
+ const allTime = ref()
|
|
|
+ const biNum = ref()
|
|
|
+ const currentTime = ref()
|
|
|
+ const videoStart = () => {
|
|
|
+ videoContext.value = videoRef.value
|
|
|
+ if (initialtime.value > 0) {
|
|
|
+ videoContext.value.currentTime = initialtime.value
|
|
|
+ timeStamp1.value = initialtime.value
|
|
|
+ }
|
|
|
+ }
|
|
|
+ nextTick(() => {
|
|
|
+ videoStart()
|
|
|
+ })
|
|
|
+ const timeUpdate = (e) => {
|
|
|
+ //获取当前播放时间 durationinitialtime
|
|
|
+ if (timeStamp1.value != parseInt(e.target.currentTime)) {
|
|
|
+ allTime.value = parseInt(e.target.duration) //视频总时长(秒)
|
|
|
+ //对播放的时间进行整
|
|
|
+ timeStamp1.value = parseInt(e.target.currentTime) //播放进度 (秒)
|
|
|
+ biNum.value = Math.floor((timeStamp1.value / allTime.value) * 10000) / 100 //暂时没用到
|
|
|
+ currentTime.value = e.target.currentTime
|
|
|
+ if (newsschedule.value < 90) {
|
|
|
+ //newsschedule.value 请求接口获取的参数就是判断当前观看的时长是否小于90 小于90就禁止拖动进度条
|
|
|
+
|
|
|
+ if (e.srcElement.currentTime - currTime.value > 3) {
|
|
|
+ //这里拖动进度条时间 - 当前观看的时长 > 3秒 这边判定它为拖动进度条
|
|
|
+ e.srcElement.currentTime = currTime.value > maxTime.value ? currTime.value : maxTime.value
|
|
|
+ let newsVal = initialtime.value
|
|
|
+ if (newsVal) {
|
|
|
+ videoContext.value.currentTime = newsVal
|
|
|
+ }
|
|
|
+ //当前用户记录观看时间 大于 实施播放时间
|
|
|
+ if (currTime.value > newsVal) {
|
|
|
+ videoContext.value.currentTime = currTime.value
|
|
|
+ }
|
|
|
+ console.log('快进了')
|
|
|
+ }
|
|
|
+ currTime.value = e.srcElement.currentTime
|
|
|
+ maxTime.value = currTime.value > maxTime.value ? currTime.value : maxTime.value
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
const rightNenuRef = ref()
|
|
|
const noteEdit = (e) => {
|
|
|
rightNenuRef.value.selectBtn({ key: 6, type: 2 }, e)
|
|
|
@@ -160,6 +227,46 @@
|
|
|
const askEdit = (e) => {
|
|
|
rightNenuRef.value.selectBtn({ key: 7, type: 4 }, e)
|
|
|
}
|
|
|
+ const videoSpeed = (e) => {
|
|
|
+ currentTimenew.value = e.startTime
|
|
|
+ }
|
|
|
+ //获取字幕内容,发送一个get请求
|
|
|
+ function GetSrtInfo(srtUrl) {
|
|
|
+ axios
|
|
|
+ .get(`${srtUrl}`)
|
|
|
+ .then(function (response) {
|
|
|
+ let textList = response.data
|
|
|
+ .split(/\n\s\n/)
|
|
|
+ .filter((item) => item != '')
|
|
|
+ .map((item, index) => {
|
|
|
+ let textItem = item.split(/\n/)
|
|
|
+ return {
|
|
|
+ index: index,
|
|
|
+ sort: textItem[0],
|
|
|
+ text: textItem[2],
|
|
|
+ startTime: ToSeconds(textItem[1].split(' --> ')[0]),
|
|
|
+ endTime: ToSeconds(textItem[1].split(' --> ')[1]),
|
|
|
+ timeLine: textItem[1]
|
|
|
+ }
|
|
|
+ })
|
|
|
+ danmuObj.value.srtInfoList = textList
|
|
|
+ console.log('解析之后的字幕内容', textList)
|
|
|
+ })
|
|
|
+ .catch(function (error) {
|
|
|
+ console.log(error)
|
|
|
+ })
|
|
|
+ }
|
|
|
+ //将时间转化为秒
|
|
|
+ function ToSeconds(t) {
|
|
|
+ var s = 0.0
|
|
|
+ if (t) {
|
|
|
+ var p = t.split(':')
|
|
|
+ for (let i = 0; i < p.length; i++) {
|
|
|
+ s = s * 60 + parseFloat(p[i].replace(',', '.'))
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return s
|
|
|
+ }
|
|
|
</script>
|
|
|
<style scoped lang="less">
|
|
|
.classTitle {
|