You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
228 lines
4.9 KiB
228 lines
4.9 KiB
<template>
|
|
<view v-html="videoHtml" id="dom-video" class="dom-video" :eventDrive="eventDrive"
|
|
:change:eventDrive="domVideo.eventHandle" :videoSrc="videoSrc" :change:videoSrc="domVideo.srcChange"
|
|
:videoProps="videoProps" :change:videoProps="domVideo.propsChange" :randomNum="randomNum"
|
|
:change:randomNum="domVideo.randomNumChange" />
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
props: {
|
|
src: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
autoplay: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
loop: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
controls: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
objectFit: {
|
|
type: String,
|
|
default: 'contain'
|
|
},
|
|
muted: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
poster: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
},
|
|
|
|
// 数据状态
|
|
data() {
|
|
return {
|
|
videoHtml: '',
|
|
videoSrc: '',
|
|
eventDrive: null,
|
|
videoProps: {},
|
|
randomNum: Math.floor(Math.random() * 100000000 + 1)
|
|
}
|
|
},
|
|
watch: {
|
|
// 监听视频资源文件更新
|
|
src: {
|
|
handler(val) {
|
|
if (!val) return
|
|
this.initVideoHtml()
|
|
setTimeout(() => {
|
|
this.videoSrc = val
|
|
}, 0)
|
|
},
|
|
immediate: true
|
|
},
|
|
// 监听首次加载
|
|
autoplay: {
|
|
handler(val) {
|
|
this.videoProps.autoplay = val
|
|
},
|
|
immediate: true
|
|
},
|
|
},
|
|
// 生命周期
|
|
mounted() {
|
|
this.initVideoHtml()
|
|
},
|
|
beforeDestroy() {
|
|
this.videoHtml = ''
|
|
},
|
|
|
|
// 方法
|
|
methods: {
|
|
// 将video的事件传递给父组件
|
|
listener(data) {
|
|
console.log('向父组件传递事件 =>', data)
|
|
this.$emit('listener', data)
|
|
},
|
|
// 初始化视频
|
|
initVideoHtml() {
|
|
this.videoHtml = `<video
|
|
src="${this.src}"
|
|
id="dom-html-video_${this.randomNum}"
|
|
class="dom-html-video"
|
|
${this.autoplay ? 'autoplay' : ''}
|
|
${this.loop ? 'loop' : ''}
|
|
${this.controls ? 'controls' : ''}
|
|
${this.muted ? 'muted' : ''}
|
|
${this.poster ? 'poster="' + this.poster + '"' : ''}
|
|
preload="auto"
|
|
playsinline
|
|
webkit-playsinline
|
|
width="100%"
|
|
height="100%"
|
|
style="object-fit: ${this.objectFit};padding:0;"
|
|
>
|
|
<source src="${this.src}" type="video/mp4">
|
|
<source src="${this.src}" type="video/ogg">
|
|
<source src="${this.src}" type="video/webm">
|
|
</video>
|
|
`
|
|
// console.log('视频html =>', this.videoHtml)
|
|
},
|
|
resetEventDrive() {
|
|
this.eventDrive = null
|
|
},
|
|
// 将service层的事件/数据 => 传递给renderjs层
|
|
play() {
|
|
this.eventDrive = 'play'
|
|
},
|
|
pause() {
|
|
this.eventDrive = 'pause'
|
|
},
|
|
stop() {
|
|
this.eventDrive = 'stop'
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<script module="domVideo" lang="renderjs">
|
|
export default {
|
|
data() {
|
|
return {
|
|
video: null,
|
|
num: '',
|
|
options: {},
|
|
}
|
|
},
|
|
mounted() {
|
|
this.initVideoEvent()
|
|
},
|
|
methods: {
|
|
initVideoEvent() {
|
|
setTimeout(() => {
|
|
let video = document.getElementById(`dom-html-video_${this.num}`)
|
|
this.video = video
|
|
// 监听视频事件
|
|
video.addEventListener('play', () => {
|
|
this.$ownerInstance.callMethod('listener', {
|
|
name: 'play',
|
|
currentTime: 0,
|
|
duration: this.video.duration
|
|
})
|
|
})
|
|
video.addEventListener('pause', () => {
|
|
this.$ownerInstance.callMethod('listener', {
|
|
name: 'pause',
|
|
currentTime: this.video.currentTime,
|
|
duration: this.video.duration
|
|
})
|
|
})
|
|
video.addEventListener('ended', () => {
|
|
this.$ownerInstance.callMethod('listener', {
|
|
name: 'ended',
|
|
currentTime: this.video.currentTime,
|
|
duration: this.video.duration
|
|
})
|
|
this.$ownerInstance.callMethod('resetEventDrive')
|
|
})
|
|
|
|
}, 100)
|
|
|
|
},
|
|
eventHandle(eventType) {
|
|
if (eventType) {
|
|
this.video = document.getElementById(`dom-html-video_${this.num}`)
|
|
if (!this.video) {
|
|
console.error(`Cannot find video element with id: dom-html-video_${this.num}`);
|
|
return;
|
|
}
|
|
if (eventType === 'play') {
|
|
this.video.play()
|
|
} else if (eventType === 'pause') {
|
|
this.video.pause()
|
|
} else if (eventType === 'stop') {
|
|
this.video.pause()
|
|
this.video.currentTime = 0;
|
|
}
|
|
}
|
|
},
|
|
srcChange(val) {
|
|
// 实现视频的第一帧作为封面,避免视频展示黑屏
|
|
// this.initVideoEvent()
|
|
setTimeout(() => {
|
|
let video = document.getElementById(`dom-html-video_${this.num}`)
|
|
|
|
video.addEventListener('loadedmetadata', () => {
|
|
|
|
console.log('this.options', this.options)
|
|
let { autoplay } = this.options
|
|
if (!autoplay) {
|
|
video.pause()
|
|
} else {
|
|
video.play()
|
|
}
|
|
})
|
|
}, 100)
|
|
},
|
|
propsChange(obj) {
|
|
this.options = obj
|
|
},
|
|
randomNumChange(val) {
|
|
this.num = val
|
|
},
|
|
}
|
|
}
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
.dom-video {
|
|
overflow: hidden;
|
|
height: 100%;
|
|
padding: 0;
|
|
|
|
&-height {
|
|
height: 100%;
|
|
}
|
|
}
|
|
</style>
|