uni-app App和H5平臺(tái)使用renderjs上傳視頻截取視頻第一幀生成圖片
提示:因?yàn)閡ni-app中renderjs僅支持App和H5平臺(tái),所以該方案僅支持當(dāng)前這兩個(gè)平臺(tái)。 this.request為本人封裝的接口請(qǐng)求方法,可以替換成個(gè)人的接口請(qǐng)求方法,如有需要可在下方留言
前言
因?yàn)閡ni-app App端沒有dom概念,不支持dom操作,并且uni-app的canvas不支持繪制video。renderjs完美解決了uni-app App端的基礎(chǔ)dom操作。實(shí)現(xiàn)效果在最下方?。?/p>
一、renderjs簡介
renderjs是一個(gè)運(yùn)行在視圖層的js。它比[WXS](https://uniapp.dcloud.io/tutorial/miniprogram-subject.html#wxs)更加強(qiáng)大。它只支持app-vue和h5。
renderjs的主要作用有2個(gè):
- 大幅降低邏輯層和視圖層的通訊損耗,提供高性能視圖交互能力
- 在視圖層操作dom,運(yùn)行for web的js庫
二、創(chuàng)建index.vue文件,下方代碼均在index.vue中
1.HTML代碼
代碼如下(示例):
<template>
<view class="content">
// 邏輯層調(diào)用視圖層方法,采用監(jiān)聽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) => {
// 上傳視頻到網(wǎng)絡(luò)地址,當(dāng)然也可以使用本地地址。App、H5平臺(tái)本人都測(cè)試過,都沒問題!!!
uni.uploadFile({
url: 'http://替換成自己個(gè)上傳文件接口/api/common/upload', //僅為示例,非真實(shí)的接口地址
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}
// 這里當(dāng)時(shí)想做個(gè)平臺(tái)區(qū)分,但是后面發(fā)現(xiàn)H5平臺(tái)這種調(diào)用方式,視圖層create接受參數(shù)的時(shí)候,只能接收到newValue,但是不能接收到event, ownerInstance,所以還是統(tǒng)一使用上方操作
// 下方方法僅展示,調(diào)用還是統(tǒng)一使用上方操作
// // #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字符串,上傳網(wǎng)絡(luò)圖片
getBase64(options){
this.request({
url: 'common/base64', //僅為示例,非真實(shí)的接口地址
data: {
base64: options.base64
}
}).then(res=>{
// 拿到上傳base64圖片的網(wǎng)絡(luò)圖片
console.log(res)
})
},
}
}
</script>
3.視圖層代碼
代碼如下(示例):
<!-- 視圖層script module對(duì)應(yīng)HTML代碼中view的id-->
<script module="canvas" lang="renderjs">
export default {
methods: {
// 視圖層創(chuàng)建base64圖片
create(newValue, oldValue, ownerInstance){
// 第一次進(jìn)入為空不操作
if(newValue == null){
return
}
// 在緩存中創(chuàng)建video標(biāo)簽
var video = document.createElement("VIDEO")
// 通過setAttribute給video dom元素添加自動(dòng)播放的屬性,因?yàn)橐曨l播放才能獲取封面圖
// 設(shè)置video自動(dòng)播放屬性
video.autoplay = true
// 該設(shè)置方法無效
// video.setAttribute('autoplay', true)
// 再添加一個(gè)靜音的屬性,否則自動(dòng)播放會(huì)有聲音
// 該設(shè)置方法無效
// video.setAttribute('muted', true)
video.muted = true
// 如果報(bào)錯(cuò)Uncaught SecurityError: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.
// 可以把下面兩行代碼加上,因?yàn)槲矣玫木€上video url,所以可能拋出了異常。大概意思就是跨域了toDataURL()使用了外域資源
video.setAttribute('crossOrigin', 'anonymous')
video.crossOrigin = '*'
// 上面我們只是創(chuàng)建了video標(biāo)簽,視頻播放需要內(nèi)部的source的標(biāo)簽,scr為播放源
video.innerHTML = '<source src=' + newValue.fullurl + ' type="audio/mp4">'
// 再創(chuàng)建canvas畫布標(biāo)簽
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
// video注冊(cè)canplay自動(dòng)播放事件
// 防止video不播放,所以手動(dòng)加個(gè)播放操作
video.play()
// video播放事件
video.addEventListener('canplay', ()=>{
// 創(chuàng)建畫布的寬高屬性節(jié)點(diǎn),就是圖片的大小,單位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編碼會(huì)小很多
var base64 = canvas.toDataURL('image/jpeg') // 這就是封面圖片的base64編碼
// 傳遞數(shù)據(jù)給邏輯層
ownerInstance.callMethod('getBase64',{
base64: base64
})
// 刪除創(chuàng)建的video 、canvas dom,要不然重新選取視頻生成圖片不生效
// ps:開始有這個(gè)問題,但是后面不知道為什么又沒有了,如果發(fā)現(xiàn)生成第一次base64之后再選擇不生效,可以嘗試一下把下方注釋打開
// document.body.removeChild(video)
// document.body.removeChild(canvas)
})
}
}
}
</script>
提示:本文由本人原創(chuàng),轉(zhuǎn)載請(qǐng)注明出處!!! 如果本文對(duì)你有幫助,請(qǐng)點(diǎn)個(gè)贊吧!
實(shí)現(xiàn)效果
1.base64圖片效果
文章來源:http://www.zghlxwxcb.cn/news/detail-407771.html
2.線上圖片效果
文章來源地址http://www.zghlxwxcb.cn/news/detail-407771.html
到了這里,關(guān)于uni-app App和H5平臺(tái)上傳視頻截取視頻第一幀生成圖片的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!