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