uniapp上传预览视频组件封装
需求:要求视频拥有上传和预览功能,并且实现断点续存。
断点续存的重点在于:前端页面绑定表单值要与后端一致,这样在下一次进入页面能够请求后台接口,后台返回之前用户所填写的数据,展示在页面上,实现功能。
视频实现优化:
在uniapp中视频上传后有一个本地地址,前端可以在用户没有刷新时使用这个本地地址展示给用户,提高用户体验,因为又断点续存功能所以在用户刷新重新进入页面后,请求后台接口获取视频地址,这个地方后端可以返回一个压缩图片只有几k,当用户点击预览再展示给用户高清图。
<template>
<view class="container">
<!-- 默认展示视频第一帧 -->
<view class="image-upload-Item" v-for="(item,index) in uploadLists" :key="index">
<view class="image-upload-Item-video">
<video :disabled="false" :controls="false" :src="getFileUrl(item)">
<cover-view class="image-upload-Item-video-fixed" @click="previewVideo(getFileUrl(item))">
</cover-view>
<cover-view class="image-upload-Item-del" @click="imgDel(index)">×</cover-view>
</video>
<view class="image-upload-Item-video-fixed" @click="previewVideo(getFileUrl(item))"></view>
</view>
</view>
<!-- 上传按钮 -->
<view class="image-upload-Item image-upload-Item-add" @click="chooseFile">
<u-icon name="camera" color="#999" size="30"></u-icon>
</view>
<!-- 全屏预览视频 -->
<view class="preview-full" v-if="previewVideoSrc!=''">
<video :autoplay="true" :src="previewVideoSrc" :show-fullscreen-btn="false">
<!-- 退出全屏预览按钮 -->
<cover-view class="preview-full-close" @click="previewVideoClose"> ×
</cover-view>
</video>
</view>
</view>
</template>
<script>
export default {
data(){
return {
// 视频播放地址
previewVideoSrc: '',
// 视频播放列表
uploadLists: []
}
},
methods: {
getFileUrl(item) {
var url = item;
return url
},
previewVideo(src) {
// 预览视频
this.previewVideoSrc = src;
},
previewVideoClose(){
this.previewVideoSrc = ''
},
chooseFile(){
uni.chooseVideo({
compressed: true,
sourceType: ['camera', 'album'],
camera: 'back',
maxDuration: 60,
success: (res) => {
this.handleUploadFile(res.tempFilePath)
// 前端优化点,用户未提交前存储图片用本地地址,加快速度
// res.tempFilePath 就是一个字符串 blob:http://localhost:8081/c5bffb7f-aba2-4a2e-99fd-a8f2320afa52
}
});
},
async handleUploadFile(data) {
const _this = this;
// console.log(data)
let guid = data.substring(data.lastIndexOf('/') + 1)
const filePath = data.path || data[0];
await uni.uploadFile({
url: 'http://localhost:8080', //仅为示例,非真实的接口地址
filePath: filePath,
name: 'file',
// 带给后端的数据
// formData: {
// guid: guid
// },
success: uploadFileRes => {
console.log('uploadFileRes',uploadFileRes)
},
complete: () => {
}
});
},
imgDel(){
}
}
}
</script>
<style scoped>
.container {
display: flex;
flex-wrap: wrap;
}
.preview-full {
position: fixed;
top: 0;
left: 0;
bottom: 0;
width: 100%;
height: 100%;
z-index: 1002;
}
.preview-full video {
width: 100%;
height: 100%;
z-index: 1002;
}
.preview-full-close {
position: fixed;
right: 16px;
top: 12px;
width: 40px;
height: 40px;
line-height: 30px;
text-align: center;
z-index: 1003;
color: #fff;
font-size: 32px;
font-weight: bold;
}
.image-upload-Item {
width: 80px;
height: 80px;
position: relative;
margin: 5px;
}
.image-upload-Item-add {
font-size: 52px;
text-align: center;
color: #999999;
margin: 5px;
display: flex;
justify-content: center;
}
.image-upload-Item-video {
width: 100%;
height: 100%;
position: relative;
}
.image-upload-Item-video-fixed {
position: absolute;
top: 0;
left: 0;
bottom: 0;
width: 100%;
height: 100%;
z-index: 996;
}
.image-upload-Item video {
width: 100%;
height: 100%;
}
.image-upload-Item-del {
font-size: 25px;
position: absolute;
width: 17px;
height: 17px;
line-height: 17px;
text-align: center;
top: 0;
right: 0;
z-index: 997;
color: #999;
}
</style>