uni-app App和H5平台使用renderjs上传视频截取视频第一帧生成图片
提示:因为uni-app中renderjs仅支持App和H5平台,所以该方案仅支持当前这两个平台。 this.request为本人封装的接口请求方法,可以替换成个人的接口请求方法,如有需要可在下方留言
前言
因为uni-app App端没有dom概念,不支持dom操作,并且uni-app的canvas不支持绘制video。renderjs完美解决了uni-app App端的基础dom操作。实现效果在最下方!!
一、renderjs简介
renderjs是一个运行在视图层的js。它比[WXS](https://uniapp.dcloud.io/tutorial/miniprogram-subject.html#wxs)更加强大。它只支持app-vue和h5。
renderjs的主要作用有2个:
- 大幅降低逻辑层和视图层的通讯损耗,提供高性能视图交互能力
- 在视图层操作dom,运行for web的js库
二、创建index.vue文件,下方代码均在index.vue中
1.HTML代码
代码如下(示例):
<template>
<view class="content">
// 逻辑层调用视图层方法,采用监听data中变量改变的方法
<view id="canvas" class="canvas" :prop="newVal" :change:prop="canvas.create"></view>
<button @click="choose">chooseVideo</button>
</view>
</template>
2.逻辑层代码
代码如下(示例):
<!-- 逻辑层script -->
<script>
export default {
data() {
return {
newVal: null
};
},
methods: {
choose(){
// 选取视频文件,拿到本地地址
uni.chooseVideo({
sourceType: ['camera', 'album'],
success: (blod)=>{
// 获取视频信息,拿到宽高信息
uni.getVideoInfo({
src: blod.tempFilePath,
success: (info) => {
// 上传视频到网络地址,当然也可以使用本地地址。App、H5平台本人都测试过,都没问题!!!
uni.uploadFile({
url: 'http://替换成自己个上传文件接口/api/common/upload', //仅为示例,非真实的接口地址
filePath: blod.tempFilePath,
name: 'file',
formData: {
'token': uni.getStorageSync('userInfo').token
},
success: src => {
// fullurl也可以使用本地地址,上传选择文件获取到的 => blod.tempFilePath
this.newVal = {fullurl: JSON.parse(src.data).data.fullurl, width: info.width, height: info.height}
// 这里当时想做个平台区分,但是后面发现H5平台这种调用方式,视图层create接受参数的时候,只能接收到newValue,但是不能接收到event, ownerInstance,所以还是统一使用上方操作
// 下方方法仅展示,调用还是统一使用上方操作
// // #ifdef APP-PLUS
// this.newVal = {fullurl: JSON.parse(src.data).data.fullurl, width: info.width, height: info.height}
// // #endif
// // #ifdef H5
// this.create({fullurl: JSON.parse(src.data).data.fullurl, width: info.width, height: info.height})
// // #endif
},
complete: all => {
console.log(JSON.parse(all.data))
}
})
}
})
}
})
},
// 逻辑层拿到base64字符串,上传网络图片
getBase64(options){
this.request({
url: 'common/base64', //仅为示例,非真实的接口地址
data: {
base64: options.base64
}
}).then(res=>{
// 拿到上传base64图片的网络图片
console.log(res)
})
},
}
}
</script>
3.视图层代码
代码如下(示例):
<!-- 视图层script module对应HTML代码中view的id-->
<script module="canvas" lang="renderjs">
export default {
methods: {
// 视图层创建base64图片
create(newValue, oldValue, ownerInstance){
// 第一次进入为空不操作
if(newValue == null){
return
}
// 在缓存中创建video标签
var video = document.createElement("VIDEO")
// 通过setAttribute给video dom元素添加自动播放的属性,因为视频播放才能获取封面图
// 设置video自动播放属性
video.autoplay = true
// 该设置方法无效
// video.setAttribute('autoplay', true)
// 再添加一个静音的属性,否则自动播放会有声音
// 该设置方法无效
// video.setAttribute('muted', true)
video.muted = true
// 如果报错Uncaught SecurityError: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.
// 可以把下面两行代码加上,因为我用的线上video url,所以可能抛出了异常。大概意思就是跨域了toDataURL()使用了外域资源
video.setAttribute('crossOrigin', 'anonymous')
video.crossOrigin = '*'
// 上面我们只是创建了video标签,视频播放需要内部的source的标签,scr为播放源
video.innerHTML = '<source src=' + newValue.fullurl + ' type="audio/mp4">'
// 再创建canvas画布标签
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
// video注册canplay自动播放事件
// 防止video不播放,所以手动加个播放操作
video.play()
// video播放事件
video.addEventListener('canplay', ()=>{
// 创建画布的宽高属性节点,就是图片的大小,单位PX
var anw = document.createAttribute("width");
anw.nodeValue = newValue.width;
var anh = document.createAttribute("height");
anh.nodeValue = newValue.height;
canvas.setAttributeNode(anw);
canvas.setAttributeNode(anh);
// 画布渲染
ctx.drawImage(video, 0, 0, newValue.width, newValue.height);
// 生成base64图片,指定type为jpeg格式生成的图片base64编码会小很多
var base64 = canvas.toDataURL('image/jpeg') // 这就是封面图片的base64编码
// 传递数据给逻辑层
ownerInstance.callMethod('getBase64',{
base64: base64
})
// 删除创建的video 、canvas dom,要不然重新选取视频生成图片不生效
// ps:开始有这个问题,但是后面不知道为什么又没有了,如果发现生成第一次base64之后再选择不生效,可以尝试一下把下方注释打开
// document.body.removeChild(video)
// document.body.removeChild(canvas)
})
}
}
}
</script>
提示:本文由本人原创,转载请注明出处!!! 如果本文对你有帮助,请点个赞吧!
实现效果
1.base64图片效果
文章来源:https://www.toymoban.com/news/detail-407771.html
2.线上图片效果
文章来源地址https://www.toymoban.com/news/detail-407771.html
到了这里,关于uni-app App和H5平台上传视频截取视频第一帧生成图片的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!