|
@@ -1,6 +1,6 @@
|
|
import { defineComponent, nextTick, onMounted, reactive, toRefs, watch } from 'vue'
|
|
import { defineComponent, nextTick, onMounted, reactive, toRefs, watch } from 'vue'
|
|
-import 'plyr/dist/plyr.css'
|
|
|
|
-import Plyr from 'plyr'
|
|
|
|
|
|
+// import 'plyr/dist/plyr.css'
|
|
|
|
+// import Plyr from 'plyr'
|
|
import { ref } from 'vue'
|
|
import { ref } from 'vue'
|
|
import styles from './video.module.less'
|
|
import styles from './video.module.less'
|
|
|
|
|
|
@@ -45,9 +45,26 @@ export default defineComponent({
|
|
isActive: {
|
|
isActive: {
|
|
type: Boolean,
|
|
type: Boolean,
|
|
default: false
|
|
default: false
|
|
|
|
+ },
|
|
|
|
+ activeModel: {
|
|
|
|
+ type: Boolean,
|
|
|
|
+ default: true
|
|
}
|
|
}
|
|
},
|
|
},
|
|
- emits: ['loadedmetadata', 'togglePlay', 'ended', 'reset', 'error', 'close'],
|
|
|
|
|
|
+ emits: [
|
|
|
|
+ 'loadedmetadata',
|
|
|
|
+ 'togglePlay',
|
|
|
|
+ 'ended',
|
|
|
|
+ 'reset',
|
|
|
|
+ 'error',
|
|
|
|
+ 'close',
|
|
|
|
+ 'play',
|
|
|
|
+ 'pause',
|
|
|
|
+ 'seeked',
|
|
|
|
+ 'seeking',
|
|
|
|
+ 'waiting',
|
|
|
|
+ 'timeupdate'
|
|
|
|
+ ],
|
|
setup(props, { emit, expose }) {
|
|
setup(props, { emit, expose }) {
|
|
const { item, isEmtry } = toRefs(props)
|
|
const { item, isEmtry } = toRefs(props)
|
|
const data = reactive({
|
|
const data = reactive({
|
|
@@ -72,7 +89,7 @@ export default defineComponent({
|
|
let playTimer = null as any
|
|
let playTimer = null as any
|
|
// 切换音频播放
|
|
// 切换音频播放
|
|
const onToggleAudio = (state: 'play' | 'pause') => {
|
|
const onToggleAudio = (state: 'play' | 'pause') => {
|
|
- console.log(state, 'state')
|
|
|
|
|
|
+ // console.log(state, 'state')
|
|
clearTimeout(playTimer)
|
|
clearTimeout(playTimer)
|
|
if (state === 'play') {
|
|
if (state === 'play') {
|
|
playTimer = setTimeout(() => {
|
|
playTimer = setTimeout(() => {
|
|
@@ -112,41 +129,41 @@ export default defineComponent({
|
|
data.timer = null
|
|
data.timer = null
|
|
}, 300)
|
|
}, 300)
|
|
}
|
|
}
|
|
- onMounted(() => {
|
|
|
|
- videoItem.value = TCPlayer(videoID, {
|
|
|
|
- appID: '',
|
|
|
|
- controls: false
|
|
|
|
- // autoplay: true
|
|
|
|
- }) // player-container-id 为播放器容器 ID,必须与 html 中一致
|
|
|
|
- if (videoItem.value) {
|
|
|
|
|
|
+
|
|
|
|
+ const __initVideo = () => {
|
|
|
|
+ if (videoItem.value && props.item.id) {
|
|
videoItem.value.poster(props.item.coverImg) // 封面
|
|
videoItem.value.poster(props.item.coverImg) // 封面
|
|
- videoItem.value.src(isEmtry.value ? '' : item.value.content) // url 播放地址
|
|
|
|
|
|
+ videoItem.value.src(item.value.content) // url 播放地址
|
|
|
|
|
|
// 初步加载时
|
|
// 初步加载时
|
|
- videoItem.value.one('loadedmetadata', (e: any) => {
|
|
|
|
- // console.log(' Loading metadata')
|
|
|
|
|
|
+ videoItem.value.on('loadedmetadata', (e: any) => {
|
|
|
|
+ console.log(' Loading metadata')
|
|
|
|
|
|
// 获取时长
|
|
// 获取时长
|
|
data.duration = videoItem.value.duration()
|
|
data.duration = videoItem.value.duration()
|
|
-
|
|
|
|
// 必须在当前元素
|
|
// 必须在当前元素
|
|
|
|
|
|
if (item.value.autoPlay && videoItem.value && props.isActive) {
|
|
if (item.value.autoPlay && videoItem.value && props.isActive) {
|
|
- videoItem.value?.play()
|
|
|
|
|
|
+ // videoItem.value?.play()
|
|
|
|
+ nextTick(() => {
|
|
|
|
+ videoItem.value.currentTime(0)
|
|
|
|
+ nextTick(handlePlayVideo)
|
|
|
|
+ })
|
|
}
|
|
}
|
|
emit('loadedmetadata', videoItem.value)
|
|
emit('loadedmetadata', videoItem.value)
|
|
})
|
|
})
|
|
- videoItem.value.on('timeupdate', () => {
|
|
|
|
- if (!props.isActive) {
|
|
|
|
- console.log('不是激活的视频,如果在播放,就暂停')
|
|
|
|
- videoRef.value.pause()
|
|
|
|
- }
|
|
|
|
- })
|
|
|
|
|
|
+ // videoItem.value.on('timeupdate', () => {
|
|
|
|
+ // if (!props.isActive) {
|
|
|
|
+ // console.log('不是激活的视频,如果在播放,就暂停')
|
|
|
|
+ // videoRef.value.pause()
|
|
|
|
+ // }
|
|
|
|
+ // })
|
|
|
|
|
|
// 视频播放时加载
|
|
// 视频播放时加载
|
|
videoItem.value.on('timeupdate', () => {
|
|
videoItem.value.on('timeupdate', () => {
|
|
if (data.timer) return
|
|
if (data.timer) return
|
|
data.currentTime = videoItem.value.currentTime()
|
|
data.currentTime = videoItem.value.currentTime()
|
|
|
|
+ emit('timeupdate')
|
|
})
|
|
})
|
|
|
|
|
|
// 视频播放结束
|
|
// 视频播放结束
|
|
@@ -160,6 +177,18 @@ export default defineComponent({
|
|
data.playState = 'pause'
|
|
data.playState = 'pause'
|
|
changePlayBtn('pause')
|
|
changePlayBtn('pause')
|
|
emit('togglePlay', true)
|
|
emit('togglePlay', true)
|
|
|
|
+ emit('pause')
|
|
|
|
+ })
|
|
|
|
+
|
|
|
|
+ videoItem.value.on('seeked', () => {
|
|
|
|
+ emit('seeked')
|
|
|
|
+ })
|
|
|
|
+
|
|
|
|
+ videoItem.value.on('seeking', () => {
|
|
|
|
+ emit('seeking')
|
|
|
|
+ })
|
|
|
|
+ videoItem.value.on('waiting', () => {
|
|
|
|
+ emit('waiting')
|
|
})
|
|
})
|
|
|
|
|
|
videoItem.value.on('play', () => {
|
|
videoItem.value.on('play', () => {
|
|
@@ -169,26 +198,94 @@ export default defineComponent({
|
|
videoItem.value.muted = false
|
|
videoItem.value.muted = false
|
|
videoItem.value.volume = 1
|
|
videoItem.value.volume = 1
|
|
}
|
|
}
|
|
- // console.log('开始播放', item.value)
|
|
|
|
if (!item.value.autoPlay && !item.value.isprepare && videoItem.value) {
|
|
if (!item.value.autoPlay && !item.value.isprepare && videoItem.value) {
|
|
// 加载完成后,取消静音播放
|
|
// 加载完成后,取消静音播放
|
|
- console.log(videoItem.value)
|
|
|
|
|
|
+ // console.log(videoItem.value)
|
|
videoItem.value.pause()
|
|
videoItem.value.pause()
|
|
}
|
|
}
|
|
emit('togglePlay', videoItem.value?.paused)
|
|
emit('togglePlay', videoItem.value?.paused)
|
|
|
|
+ emit('play')
|
|
})
|
|
})
|
|
|
|
|
|
// 视频播放异常
|
|
// 视频播放异常
|
|
videoItem.value.on('error', (e: any) => {
|
|
videoItem.value.on('error', (e: any) => {
|
|
|
|
+ handleErrorVideo()
|
|
emit('error')
|
|
emit('error')
|
|
console.log(e, 'error')
|
|
console.log(e, 'error')
|
|
})
|
|
})
|
|
}
|
|
}
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ let videoTimer = null as any
|
|
|
|
+ let videoTimerErrorCount = 0
|
|
|
|
+ const handlePlayVideo = () => {
|
|
|
|
+ if (videoTimerErrorCount > 5) {
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ clearTimeout(videoTimer)
|
|
|
|
+ nextTick(() => {
|
|
|
|
+ videoItem.value?.play().catch((err) => {
|
|
|
|
+ // console.log('🚀 ~ err:', err)
|
|
|
|
+ videoTimer = setTimeout(() => {
|
|
|
|
+ if (err?.message?.includes('play()')) {
|
|
|
|
+ emit('play')
|
|
|
|
+ }
|
|
|
|
+ handlePlayVideo()
|
|
|
|
+ }, 1000)
|
|
|
|
+ })
|
|
|
|
+ })
|
|
|
|
+ videoTimerErrorCount++
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ let videoErrorTimer = null as any
|
|
|
|
+ let videoErrorCount = 0
|
|
|
|
+ const handleErrorVideo = () => {
|
|
|
|
+ if (videoErrorCount > 5) {
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ clearTimeout(videoErrorTimer)
|
|
|
|
+ nextTick(() => {
|
|
|
|
+ videoErrorTimer = setTimeout(() => {
|
|
|
|
+ videoItem.value.src = props.item?.content
|
|
|
|
+ emit('play')
|
|
|
|
+ videoItem.value.load()
|
|
|
|
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
|
|
+ handleErrorVideo()
|
|
|
|
+ }, 1000)
|
|
|
|
+ })
|
|
|
|
+ videoErrorCount++
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ onMounted(() => {
|
|
|
|
+ videoItem.value = TCPlayer(videoID, {
|
|
|
|
+ appID: '',
|
|
|
|
+ controls: false
|
|
|
|
+ // autoplay: true
|
|
|
|
+ }) // player-container-id 为播放器容器 ID,必须与 html 中一致
|
|
|
|
+ __initVideo()
|
|
})
|
|
})
|
|
|
|
+
|
|
|
|
+ watch(
|
|
|
|
+ () => props.item,
|
|
|
|
+ () => {
|
|
|
|
+ __initVideo()
|
|
|
|
+ }
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ const getVideoRef = () => {
|
|
|
|
+ return videoRef.value
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ const getPlyrRef = () => {
|
|
|
|
+ return videoItem.value
|
|
|
|
+ }
|
|
expose({
|
|
expose({
|
|
changePlayBtn,
|
|
changePlayBtn,
|
|
- toggleHideControl
|
|
|
|
|
|
+ toggleHideControl,
|
|
|
|
+ getVideoRef,
|
|
|
|
+ getPlyrRef
|
|
})
|
|
})
|
|
|
|
+
|
|
watch(
|
|
watch(
|
|
() => props.isActive,
|
|
() => props.isActive,
|
|
(val) => {
|
|
(val) => {
|
|
@@ -197,11 +294,12 @@ export default defineComponent({
|
|
}
|
|
}
|
|
}
|
|
}
|
|
)
|
|
)
|
|
|
|
+
|
|
return () => (
|
|
return () => (
|
|
<div class={styles.videoWrap}>
|
|
<div class={styles.videoWrap}>
|
|
<video
|
|
<video
|
|
style={{ width: '100%', height: '100%' }}
|
|
style={{ width: '100%', height: '100%' }}
|
|
- src={isEmtry.value ? '' : item.value.content}
|
|
|
|
|
|
+ src={item.value.content}
|
|
ref={videoRef}
|
|
ref={videoRef}
|
|
id={videoID}
|
|
id={videoID}
|
|
preload="auto"
|
|
preload="auto"
|