需求:在app端通过uni.saveFile方法保存了一个mp4格式的视频文件,现在想在页面中展示这个视频文件的缩略图
方案:在网上搜了一下方案,基本都是通过创建video标签,然后通过canvas绘制图片的方式。
问题:按照网上的方案尝试了一下,发现使用网络视频连接可以成功,替换成本地视频文件地址就失败。
代码示例:
<template>
<view>
<view :vsrc="vsrc" :change:vsrc="renderScript.getVideoImg">
<video src="_doc/uniapp_save/16891612452645.mp4"></video>
</view>
<image :src="imgSrc" mode=""></image>
<!-- <button @click="setUrl('_doc/uniapp_save/16891612452645.mp4')">设置链接</button> -->
<button @click="setUrl('https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/2minute-demo.mp4')">设置链接</button>
</view>
</template>
<script>
export default {
data() {
return {
vsrc: {}, //用于renderjs通信
imgSrc: ""
}
},
methods: {
// 接收图片的base64编码
receiveImg(data) {
//data.test为返回的封面图
console.log("接收到的数据", data);
this.imgSrc = data.test
},
//视频封面图
setUrl(url) {
console.log("setUrl触发了", url);
let options = {};
options.width = 300;
options.height = 300;
options.src = url;
this.vsrc = options;
}
}
}
</script>
<script module="renderScript" lang="renderjs">
export default {
data() {
return {
test: ""
}
},
methods: {
//通过视频获得缩略图
getVideoImg(newValue, oldValue, ownerInstance, vm) {
console.log("getVideoImg触发了", newValue, oldValue);
if (newValue == null)
return;
let that = this;
// 在缓存中创建video标签
let video = document.createElement("VIDEO")
// 添加一个静音的属性,否则自动播放会有声音
// video.setAttribute('muted', true)
video.muted = true
// 通过setAttribute给video dom元素添加自动播放的属性,因为视频播放才能获取封面图
video.autoplay = true;
//允许跨域访问
video.crossOrigin = 'anonymous';
// 上面我们只是创建了video标签,视频播放需要内部的source的标签,scr为播放源
video.innerHTML = '<source src=' + newValue.src + ' type="audio/mp4">'
// 再创建canvas画布标签
let canvas = document.createElement('canvas');
let ctx = canvas.getContext('2d');
// video注册canplay自动播放事件
video.addEventListener('canplay', function() {
console.log("canplay事件触发了");
// 创建画布的宽高属性节点,就是图片的大小,单位PX
let anw = document.createAttribute("width");
anw.nodeValue = newValue.width;
let anh = document.createAttribute("height");
anh.nodeValue = newValue.height;
canvas.setAttributeNode(anw);
canvas.setAttributeNode(anh);
// 画布渲染
ctx.drawImage(video, 0, 0, newValue.width, newValue.height);
// 生成图片
that.test = canvas.toDataURL('image/png') // 这就是封面图片的base64编码
// 视频结束播放的事件
video.pause()
// 返回图片的base64编码
ownerInstance.callMethod('receiveImg', {
test: that.test
})
}, false)
},
}
}
</script>
<style lang="scss">
</style>
点击【设置连接】按钮会给vsrc赋值,触发renderScript.getVideoImg,使用网络地址时,video的canplay事件能够被触发,可以成功返回图片的base64编码,但是使用本地文件路径时,video的canplay事件没有被触发。可是我在video组件中使用本地文件路径时是可以播放的。请各位大佬帮忙看看问题出在哪?感激不尽!!!
4***@qq.com (作者)
您是说poster这个属性吗?我是想获取视频内容的第一帧作为封面图,这个属性好像不能满足需求
2023-07-20 15:28
Diligent_UI
回复 4***@qq.com: 封面的作用是视频有加载完成前展示的,获取视频内容的第一帧的时候视频已经可以播放了(即视频加载完成了),视频就是从第一帧开始播放的,感觉没有什么意义啊
2023-07-20 15:37
4***@qq.com (作者)
回复 Diligent_UI: 感谢您的回复~~然后我想做的不是在页面展示<video>的列表,而是一个由视频第一帧图片所组成的图片列表,然后点击图片可以播放视频。所以这里我需要先获取各个视频的第一帧图片的数组然后再展示到页面上。可能是我描述的不够清楚,误导了您。。
2023-07-21 09:42
再也不喝奶茶了
回复 4***@qq.com: 您好,我跟您有一样的需求,请问您解决了吗
2024-03-27 11:57
希望之风
回复 再也不喝奶茶了: 请问有找到兼容ios和安卓的截取video视频封面的插件了吗
2024-07-06 15:07
8***@qq.com
回复 4***@qq.com: 您好,我有一样的需求,请问有解决方法吗?
2024-07-23 14:57