sync:修复app端video层级过高问题 839a01f8b5

pull/132/MERGE
YunaiV 2025-04-27 23:53:20 +08:00
parent c10a1c9adc
commit 9e96df4651
2 changed files with 248 additions and 9 deletions

View File

@ -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>

View File

@ -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;