sync:修复app端video层级过高问题 839a01f8b5
parent
c10a1c9adc
commit
9e96df4651
|
@ -0,0 +1,213 @@
|
|||
<!-- 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: '',
|
||||
},
|
||||
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)
|
||||
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">
|
||||
<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('videoEvent', 'play')
|
||||
})
|
||||
video.addEventListener('pause', () => {
|
||||
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}`)
|
||||
|
||||
if (eventType === 'play') {
|
||||
this.video.play()
|
||||
} else if (eventType === 'pause') {
|
||||
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>
|
|
@ -1,5 +1,6 @@
|
|||
<template>
|
||||
<view class="ui-video-wrap">
|
||||
<!-- #ifndef APP-PLUS -->
|
||||
<video
|
||||
:id="`sVideo${uid}`"
|
||||
class="radius"
|
||||
|
@ -18,12 +19,38 @@
|
|||
@pause="pause"
|
||||
@ended="end"
|
||||
:poster="poster"
|
||||
:autoplay="autoplay"
|
||||
>
|
||||
<!-- #ifdef APP-PLUS -->
|
||||
<cover-view :style="{ transform: 'translateX(' + moveX + 'px)' }" />
|
||||
<!-- #endif -->
|
||||
</video>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef APP-PLUS -->
|
||||
<dom-video
|
||||
ref="domVideo"
|
||||
class="radius"
|
||||
:style="[{ height: height + 'rpx' }]"
|
||||
object-fit="contain"
|
||||
:controls="true"
|
||||
:show-progress="false"
|
||||
:show-fullscreen-btn="false"
|
||||
:show-play-btn="false"
|
||||
:show-bottom-progress="false"
|
||||
:autoplay="false"
|
||||
:src="src"
|
||||
@play="play"
|
||||
@pause="pause"
|
||||
@ended="end"
|
||||
/>
|
||||
<!-- #endif -->
|
||||
<!-- <view
|
||||
v-show="!state.isplay"
|
||||
class="poster-wrap radius"
|
||||
:style="{ height: height + 'px' }"
|
||||
@click="beforePlay"
|
||||
>
|
||||
<image class="poster-image" mode="aspectFill" :src="poster" v-if="poster" />
|
||||
<view class="play-icon ss-flex ss-row-center ss-col-center">
|
||||
<text class="cicon-play-arrow ss-font-40"></text>
|
||||
</view>
|
||||
</view> -->
|
||||
</view>
|
||||
</template>
|
||||
<script setup>
|
||||
|
@ -43,6 +70,7 @@
|
|||
*/
|
||||
|
||||
import { reactive, nextTick, getCurrentInstance } from 'vue';
|
||||
import DomVideo from './components/dom-video.vue';
|
||||
import sheep from '@/sheep';
|
||||
const vm = getCurrentInstance();
|
||||
|
||||
|
@ -81,7 +109,7 @@
|
|||
// 指定视频初始播放位置,单位为秒(s)
|
||||
initialTime: {
|
||||
type: Number,
|
||||
default: 1,
|
||||
default: 0,
|
||||
},
|
||||
src: {
|
||||
type: String,
|
||||
|
@ -91,10 +119,6 @@
|
|||
type: String,
|
||||
default: 'https://img1.baidu.com/it/u=1601695551,235775011&fm=26&fmt=auto',
|
||||
},
|
||||
autoplay: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
}
|
||||
});
|
||||
|
||||
// 事件
|
||||
|
@ -137,6 +161,7 @@
|
|||
const beforePlay = () => {
|
||||
uni.getNetworkType({
|
||||
success: (res) => {
|
||||
console.log(res.networkType, 'res.networkType');
|
||||
const networkType = res.networkType;
|
||||
// if (networkType === 'wifi' || networkType === 'ethernet') {
|
||||
// startPlay();
|
||||
|
@ -169,6 +194,7 @@
|
|||
.radius {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.ui-video-wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
|
Loading…
Reference in New Issue