uni 中使用video在移动端层级过高问题解决方案

问题出现背景:

项目中的轮播图中包含图片和视频,点击视频进行视频播放

遇到了什么问题:

第一个问题:使用video标签控制视频播放,但在app中层级过高,显示出现问题

<video ref="videoId" id="videoId" 
:poster="_img.cover" :src="_img.path" 
v-if="_img.type == 2" style="width: 100%; height: 100%"
>
</video> -->

在这里插入图片描述

第二个问题:把轮播图封装在了组件中,video中的一些api比如暂停等全部失效了

change(e){
	uni.createVideoContext('videoId').pause();
},

swiper 中current 改变时会触发视频暂停,但是这里并没有生效

面临的这两个问题如何解决
首先层级问题,网上有很多种解决方法
总结一下目前使用比较多的有三种方法

方法一:使用vue中的v-html属性 设置innerHTML,内容中有html结构会被解析为标签。

<view class="" v-html="type1html"></view>
this.type1html=
`<video controls
id="videoId"
@play="play"
@fullscreenchange="fullscreenchange"
style="width:100%;height:auto;border-radius: 7px;object-fit: cover;position: absolute;top:30%;" poster="${items.cover?items.cover:'https://mp-ca8a1846-6eec-4662-aa41-add050d1945c.cdn.bspapp.com/static/icon/cover.png'}">
	<source src="${items.path}">
</video>`

通过控制自动全屏播放和退出全屏播放后暂停播放,来避免页面划走后视频仍旧播放的问题,但是,出现了封装在组件中的video 的api失效的问题

这时,我在组件中api使用时添加了this指向

uni.createVideoContext('videoId', this).pause();

依旧没有生效,并且安卓端甚至无法播放视频
ios端自动就开始进行视频全屏播放
存在严重的兼容性问题

方法二:在video标签中添加cover-view

首先什么是cover-view-子绝父相
在这里插入图片描述

<video ref="videoId" id="videoId" 
:poster="_img.cover" :src="_img.path" 
v-if="_img.type == 2" style="width: 100%; height: 100%"
>
	<cover-view style="width: 90vw; height: 55vh;background-color:#fff;"></cover-view>
</video>

效果并不好,因为是包在swiper里,swiper一滚动依旧是错乱的

方法三:subnvue 创建原生子窗体,放在当前页面下

onLoad() {
			const subNvue = uni.getSubNVueById('subNvue'); // 这个id是pages.json下绑定的唯一id
			// subNvue.hide();//标识初始隐藏

			subNvue.show('none', 0, () => {
				subNvue.setStyle({
					top: '90px',
					right: '20px',
					width: '90px',
					height: '114px'
				});
			});
 
		}
```html
<template>
	<view>
		<text style="font-size: 30px;color: #f00;">这是子窗体</text>
	</view>
</template>
 
<script>
	export default {
		data() {
			return {
				
			}
		},
		methods: {
			
		}
	}
</script>
 
<style>
 
</style>

这个方法可行,但是咱们是包在swiper里的,current发生改变的时候,子窗体会出现渲染延迟问题

第四个方法:迂回方法,我们在页面最上层加一个popup弹出层

弹出层就会整体覆盖在页面最上层,把video塞进popup中去,当点击遮罩关闭时暂停视频播放
我们把swiper里注入视频的封面图,给一个点击事件,点击打开弹出层自动开始播放视频
这样swiper无论如何都不会出错

<swiper indicator-active-color="#fff" class="" :current="current" indicator-dots @change="change" style="width: 90vw; height: 55vh;background-color: #1E1F24;border-radius: 32rpx;">
	<swiper-item v-for="(_img, index) in item.swiper" :key="index" style="border-radius: 32rpx; overflow: hidden;">
		<image v-if="_img.type===1" mode="aspectFit" :src="_img.path" style="width: 90vw; height: 55vh;"></image>
		<image v-if="_img.type===2" mode="aspectFit" :src="_img.cover" style="width: 90vw; height: 55vh;" @tap="showVideo(_img)"></image>
		<u-icon v-if="_img.type===2" name="play-right-fill" color="#fff" size="44" style="position: relative;top:-30vh;left:40vw;" @tap="showVideo(_img)"></u-icon>
	</swiper-item>
</swiper>

我们给swiper塞两个东西,一张普通的图片,一张视频的封面图,用返回类型来进行判断展示
再加一个弹框

<u-popup :show="video_show" :safeAreaInsetBottom="false" :safeAreaInsetTop="false" :closeable="true"
@close='close' mode="center">
<view style='width:100vw;height:40vh;'>
	<video :controls='true' style='width:100%;height:100%;' enable-			progress-gesture='false' direction='0'
		page-gesture="true" id="myVideo" autoplay='true'
		objectFit="contain" :src="videoUrl">
	</video>
</view>
</u-popup>

点击视频封面图展示弹框

showVideo(item){
	this.video_show = true
	this.videoUrl = item.path
	// 打开弹窗时开始视频播放
	uni.createVideoContext('myVideo', this).play()
},
close() {
	this.video_show = false
	// 关闭弹窗时暂停视频播放
	uni.createVideoContext('myVideo', this).pause()
},

三端一切正常
在这里插入图片描述

至此,问题解决

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值