uni-app vue 中 在渲染层 与视图层互相传递参数 uni-app 中播放视频处理办法

161 阅读1分钟

在 uni-app 中无法播放视频处理办法,需要特别注意的是,渲染层在 .nvue 中无法使用某些功能,这一章主要介绍了在uni-app 中渲染层与视图层之间的传参与使用canvas播放mp3视频的方式

<template>
	<view>
		<!-- #ifdef APP-PLUS || H5 -->
		<view :prop="videoOptions" :change:prop="canvasRander.updateVideo"></view>
		<view id="appendCanvas" :style="{height:screenHeight+'px',width:screenWidth+'px;'}">
			
		</view>
		<!-- #endif -->
	</view>
</template>

<script>
	export default {
		data: function() {
			return {
				liveUrl1: null,
				screenHeight: 0,
				screenWidth: 0,
				videoOptions: {}
			}
		},
		// 组件加载完成
		onLoad(options) {
			let data = JSON.parse(decodeURIComponent(options['data']));
			this.liveUrl1 = data['liveUrl1'];
		},
		onReady() {
			try{
				this.screenHeight = uni.getSystemInfoSync().screenHeight;
				this.screenWidth = uni.getSystemInfoSync().screenWidth;
				this.videoOptions.screenHeight = this.screenHeight;
				this.videoOptions.screenWidth = this.screenWidth;
			}catch(e){}
		},
		mounted() {
			this.initCanvas();
		},
		methods: {
			/**
			 * canvas 播放video
			 */
			initCanvas(){
				this.videoOptions.vdoSrc = this.liveUrl1;
			},
		},
	}
</script>

<script module="canvasRander" lang="renderjs">
	var canvasElem ,appendCanvas,video = document.createElement('video'), cEl = document.createElement("canvas");;
	
	video.autoplay = true;  // 自动播放
	video.muted = true;     // 静音播放以避免浏览器自动播放限制
	video.loop = true;      // 循环播放
	cEl.id = "appendCanvasElem"
	export default {
		mounted() {
			canvasElem = document.getElementById('canvasVideo');
			appendCanvas = document.getElementById('appendCanvas');
		},
		methods: {
			updateVideo(videoOptions) {
				if(!videoOptions.vdoSrc){
					return ;
				};
				video.src = videoOptions.vdoSrc;// || "https://www.runoob.com/try/demo_source/movie.mp4";  // 替换为你的实际视频路径
				cEl.style = `width: ${videoOptions.screenWidth}px;height: ${videoOptions.screenHeight}px`;
				appendCanvas.appendChild(cEl);
				// 2. 找到 canvas 元素
				const context = cEl.getContext('2d');
				// 3. 当视频开始播放时,在 canvas 上绘制视频帧
				video.addEventListener('play', () => {
					function drawVideoFrame() {
						if (!video.paused && !video.ended) {
							// 将当前视频帧绘制到 canvas 上
							context.drawImage(video, 0, 0, cEl.width, cEl.height);
							// 请求下一帧的绘制
							requestAnimationFrame(drawVideoFrame);
						}
					}
					drawVideoFrame();
				});

				// 可选:在视频加载后手动开始播放
				video.addEventListener('loadeddata', () => {
					video.play();
				});
			}
		}
	}
</script>

<style lang="scss">
	#appendCanvasElem,
	#appendCanvas{
		position: absolute;
		top: 0;
		left: 0;
		bottom: 0;
		right: 0;
		overflow: hidden;
	}
</style>

传参方案

<template>
    // 这里的 prop 是可以传递给 renderjs 的参数  :change:prop 是当属性改变时会参守 renderjs 中的 canvasRander 调用其中的方法 updateVideo 实现方法调用与传参
    <view :prop="videoOptions" :change:prop="canvasRander.updateVideo"></view>	
</template>
<script>
    export default {
            data: function() {
                return {
                    // 这里是传到渲染层的参数
                    videoOptions: {}
                }
            },
            methods: {
                /**
                 * 获取图片信息
                 */
                getImageInfo(image) {
                        console.log(image,"image")
                }
            }
    }
</script>
<script module="canvasRander" lang="renderjs">
	export default {
		methods: {
			updateVideo(data) {
				// 创建video 播放视频;
				// 播放后通过属性将图片每一帖传入
				// 通过方法渲染图片
				
				// 渲染层调用 视图层的方法  getImageInfo
				this.$ownerInstance.callMethod("getImageInfo", { 
					test: "参数传参完成"
				})
				
				console.log(data,"data")
						
			},
		}
	}
</script>