uniapp-vue项目中需要播放视频,uniapp的video组件在层级太高,无法遮挡,所以使用原生dom的video标签在APP中播放视频,可以被其他元素进行覆盖、遮挡,页面具有更高的定制性
<!-- eslint-disable --> <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: '', // 'http://mirror.aarnet.edu.au/pub/TED-talks/911Mothers_2010W-480p.mp4', // 'https://www.w3school.com.cn/i/movie.ogg', // 'https://cesium.com/public/SandcastleSampleData/big-buck-bunny_trailer.mp4', }, 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(); }, // 方法 methods: { // 将video的事件传递给父组件 videoEvent(data) { console.log('向父组件传递事件 =>', data); if (data === 'pause') { // 特定处理 iOS this.eventDrive = 'play'; } this.$emit(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"> </video> `; console.log('视频html =>', this.videoHtml); }, resetEventDrive() { this.eventDrive = null; }, // 将service层的事件/数据 => 传递给renderjs层 play() { this.eventDrive = 'play'; }, pause() { console.log('向父组件传递事件3 =>0'); 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('videoEvent', 'play') }) video.addEventListener('pause', () => { console.log('向父组件传递事件3 =>'); this.$ownerInstance.callMethod('videoEvent', 'pause') }) video.addEventListener('ended', () => { this.$ownerInstance.callMethod('videoEvent', 'ended') this.$ownerInstance.callMethod('resetEventDrive') }) }, 100) }, eventHandle(eventType) { if (eventType) { this.video = document.getElementById(`dom-html-video_${this.num}`) console.log('向父组件传递事件32 =>'); if (eventType === 'play') { this.video.play() } else if (eventType === 'pause') { console.log('向父组件传递事件31 =>'); this.video.pause() } else if (eventType === 'stop') { this.video.stop() } } }, srcChange(val) { // 实现视频的第一帧作为封面,避免视频展示黑屏 this.initVideoEvent() setTimeout(() => { let video = document.getElementById(`dom-html-video_${this.num}`) video.addEventListener('loadedmetadata', () => { let { autoplay } = this.options video.play() if (!autoplay) { video.pause() } }) }, 0) }, 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>
使用方法:
<view class=""> <dom-video :key="i" ref="domVideo" :class="{ playing: n.playing }" class="animation-container" v-if="state.botInfo[n.urlField]" object-fit="cover" :controls="false" :show-progress="false" :show-fullscreen-btn="false" :show-play-btn="false" :show-bottom-progress="false" :show-loading="false" :enable-progress-gesture="false" :enable-play-gesture="false" :auto-pause-if-navigate="false" :auto-pause-if-open-native="false" :autoplay="true" :loop="true" :muted="true" :show-controls="false" :style="{ opacity: !n.visibleField || state[n.visibleField] ? '1' : '0', }" :src="state.botInfo[n.urlField]" @play="n.playing = true" @pause="videoPause" @ended="videoEnded" /> </view>
来源地址:https://ext.dcloud.net.cn/plugin?id=11304
标签:uniapp,play,层级,val,default,pause,video,组件 From: https://www.cnblogs.com/ljcgood66/p/17963576