搜索
您的当前位置:首页正文

uniapp 在 APP中使用video 遇到的问题及解决方式-第一帧黑屏

来源:吉趣旅游网

解决在uniapp项目在 APP端使用video的第一帧黑屏问题、轮播图中左右滑动不了问题、无法操作视频的播放暂停等

(此方式只适配APP端,小程序/H5 需要使用条件编译,再写一套代码)

以下方式在APP端中,会存在首屏加载的时候是黑屏,不能像在H5中会显示第一帧图像

//正常使用video的方式
<video class="video" :src="video" :autoplay="autoplay" :controls="false" object-fit="cover" :enable-progress-gesture="false">
	<cover-view class="btn">跳过动画</cover-view>
</video>

以下方式在APP端中,会存在轮播图中左右滑动不了

//正常使用video的方式
<swiper class="swiper" @change="swiperChange">
	<swiper-item>
		<video class="video" :src="video"></video>
	</swiper-item>
	<swiper-item>
		<image class="image" :src="image"></image>
	</swiper-item>
	<swiper-item>
		<image class="image" :src="image"></image>
	</swiper-item>
</swiper>

以下方式在APP端中,可以解决第一帧黑屏,及轮播图中左右滑动不了的问题。
但是使用此方式无法直接操作视频(也就是没办法直接给video添加@play=“play()”事件,从而去操作播放暂停)

//通过v-html插入视图的方式
<swiper class="swiper" @change="swiperChange">
	<swiper-item>
		<view class="dom-video" v-html="html_video"></view>
	</swiper-item>
</swiper>

onLoad(option) {
	this.html_video = `<video class="video" id="dom-html-video" src="${this.video}" autoplay></video>`
}

解决方式:需要使用到renderjs
在APP端是没有办法直接使用 document.getElementById 方式的
而 renderjs 给我们提供了获取dom的方式
(注意:renderjs即视图层,与逻辑层是分离的,所以无法直接通过this通信)

什么是逻辑层?视图层?

//html
<template>
	<view>
		<swiper class="swiper" @change="swiperChange">
			<swiper-item>
				<view v-html="html_video"></view>
			</swiper-item>
		</swiper>
	</view>
</template>
//逻辑层
<script>
export default {
	data() {
		return {
		    str:"逻辑层的数据"
		}
	},
	onLoad(option) {
		this.test()
	}
	methods: {
	    test(){
			console.log(this.str) //逻辑层的数据
	    }}
}
</script>
//视图层
<script module="domVideo" lang="renderjs">
 export default {
	data() {
		return {
		    str:"视图层的数据",
		}
	},
	mounted() {
		this.test()
	},
	methods: {
	    test(){
			console.log(this.str) //视图层的数据
	    }
	}
}
</script>
//样式
<style lang="less" scoped>
	.swiper{}
</style>	

视图层发送数据,逻辑层接收数据方式:

//逻辑层
<script>
export default {
	data() {
		return {
		    str:"逻辑层的数据"
		}
	},
	onLoad(option) {
		this.html_video = `<video class="video" id="dom-html-video" src="${this.video}" autoplay></video>`
	}
	methods: {
	    //接收视图层传入的数据(绑定方式:方法名称一致)
		ended(e){
		    console.log('ended', e) //打印1
		},
	}
}
</script>
//视图层
<script module="domVideo" lang="renderjs">
 export default {
	data() {
		return {
			str:"视图层的数据"
		    video:'',
		}
	},
	mounted() {
		this.initVideoEvent()
	},
	methods: {
	    initVideoEvent(){
	    	setTimeout(() => {
	    		//在视图层可以直接获取dom
	    		let video = document.getElementById(`dom-html-video`)
	    		// 监听视频事件
	    		video.addEventListener('ended', () => {
	    			//发送数据给逻辑层
	    			this.$ownerInstance.callMethod('ended', '1'); 
	    		})
	    	}, 100)	
	    },
	}
}
</script>
//样式
<style lang="less" scoped>
	.swiper{}
</style>	

逻辑层发送数据,视图层接收数据方式:

//html
<template>
	<view>
		<swiper class="swiper" @change="swiperChange">
			<swiper-item @tap="_videoTap">
				//通过视图层的 <script module="domVideo" lang="renderjs"> 绑定
				//方式一:直接调用视图层的事件 (不能用this.domVideo.rdPlay)
				<view @tap="domVideo.rdPlay" v-html="html_video"></view>
				//方法二:通过:change:变量名 调用视图层的事件(要先传入此变量)
				<view 
					:isBofan="isBofan"
					:change:isBofan="domVideo.eventHandle"
					id="domVideo" v-html="html_video">
				</view>
			</swiper-item>
		</swiper>
	</view>
</template>
//逻辑层
<script>
export default {
	data() {
		return {
		    str:"逻辑层的数据"
		}
	},
	onLoad(option) {
		this.html_video = `<video class="video" id="dom-html-video" src="${this.video}" autoplay></video>`
	}
	methods: {
	    //点击 显示隐藏播放按钮
        _videoTap(){
            this.isBofan = !this.isBofan
        },
	}
}
</script>
//视图层
<script module="domVideo" lang="renderjs">
 export default {
	data() {
		return {
			str:"视图层的数据"
		    video:'',
		}
	},
	mounted() {
		
	},
	methods: {
		eventHandle(event){
		     if(event){
		         this.rdPlay()
		     } else {
		         this.rdPause()
		     }
		 },
		 rdPlay(){
		     this.video = document.getElementById(`dom-html-video`)
		     this.video.play()
		 },
		 rdPause(){
		     this.video = document.getElementById(`dom-html-video`)
		     this.video.pause()
		 },
	}
}
</script>
//样式
<style lang="less" scoped>
	.swiper{}
</style>	

因篇幅问题不能全部显示,请点此查看更多更全内容

Top