欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

上传视频预览 Vue 完整代码(获取视频的第一帧)

最编程 2024-03-08 14:08:49
...
<template> <div> <el-upload ref="upload" :limit="uploadLimit" list-type="picture-card" :accept="uploadAccept" :before-upload="beforeUpload" :headers="headers" :on-preview="handlePreview" :on-success="handleSuccess" :on-remove="handleRemove" :on-exceed="handleExceed" :action="action" :file-list="fileList" > <i slot="default" class="el-icon-plus" /> </el-upload> <!-- 预览部分 --> <el-dialog :visible.sync="dialogImage"> <img width="400px" :src="dialogUrl" alt=""> </el-dialog> <el-dialog :visible.sync="dialogVideo"> <video width="600px" :src="dialogUrl" controls /> </el-dialog> <div v-if="videoList[0]" style="position:absolute; right: 999999px"> <canvas id="mycanvas" /> <video id="upvideo" :src="videoList[0].url" style="width:320px;height:200px;" controls="controls" /> </div> </div> </template> <script> export default { data() { return { uploadLimit: 1, imgType: 1, // 1图片 2视频 worksUpdateType: 3 // 1图片 2视频 3均可 } }, computed: { uploadAccept() { let text = '.png, .jpg, .mp4' switch (this.worksUpdateType) { case 1: text = '.png, .jpg' break case 2: text = '.mp4' break case 3: text = '.png, .jpg, .mp4' break } return text } }, methods: { // 上传文件大小、格式限制 beforeUpload(file) { if (file.type !== 'video/mp4') { this.uploadLimit = 20 this.imgType = 1 } else { const isHaveImg = this.fileList.some(item => item.suffix === 'jpg' || item.suffix === 'png') if (isHaveImg && (this.videoSrc !== '' || this.imgType === 1)) { this.handleExceed() return false } this.uploadLimit = 1 this.imgType = 2 } const testmsg = file.name.substring(file.name.lastIndexOf('.') + 1) const extension = testmsg === 'mp4' const isJPG = file.type === 'image/jpg' || file.type === 'image/jpeg' || file.type === 'image/png' const isLt5M = file.size / 1024 / 1024 < 5 const isLt2M = file.size / 1024 / 1024 < 100 if (isJPG) { if (!isLt5M) { this.$message.error('上传图片大小不能超过 5MB!') } } else if (extension) { if (!isLt2M) { this.$message.error('上传视频大小不能超过 100MB!') } } const n = this.worksUpdateType if (n === 1 && !isJPG) { this.$message.error('上传图片只能是 JPG、PNG格式!') return isJPG && isLt5M } else if (n === 2 && !extension) { this.$message.error('上传视频只能是 MP4格式!') return extension && isLt2M } else if (n === 3 && !isJPG && !extension) { this.$message.error('上传文件只能是 JPG、PNG、MP4格式!') return (isJPG && isLt5M) || (extension && isLt2M) } }, // 上传成功图片/视频区分处理(如果为视频截取第一帧) handleSuccess(res, file, fileList) { let newFile = null if (res.success) { newFile = res.data.mapList[0] if (newFile.suffix === 'mp4') { this.fileList = [] this.fileList.push(newFile) this.videoList = [newFile] this.videoSrc = newFile.url // 需要DOM更新后操作,否则会报错 this.$nextTick(() => { this.findvideocover(newFile.url) }) } else { this.fileList.push(newFile) this.form.imgPath = newFile.url } } }, // 截取视频第一帧作为播放前默认图片 async findvideocover(url, file) { const video = document.querySelector('#upvideo') // 获取视频对象 video.src = url // url地址 url跟 视频流是一样的 var canvas = document.getElementById('mycanvas') // 获取 canvas 对象 const ctx = canvas.getContext('2d') // 绘制2d video.crossOrigin = 'anonymous' // 解决跨域问题,也就是提示污染资源无法转换视频 video.currentTime = 1 // 第一帧 video.oncanplay = () => { canvas.width = video.clientWidth // 获取视频宽度 canvas.height = video.clientHeight // 获取视频高度 // 利用canvas对象方法绘图 ctx.drawImage(video, 0, 0, video.clientWidth, video.clientHeight) // 转换成base64形式 this.imgsrc = canvas.toDataURL('image/png') // 截取后的视频封面 // 将base64转化成图片上传获取地址url const res = this.dataURLtoFileFun(this.imgsrc, 'file.jpg') this.getVideoImgUrl(res) } }, dataURLtoFileFun(dataurl, filename) { // 将base64转换为文件,dataurl为base64字符串,filename为文件名(必须带后缀名,如.jpg,.png) const arr = dataurl.split(',') const mime = arr[0].match(/:(.*?);/)[1] const bstr = atob(arr[1]) let n = bstr.length const u8arr = new Uint8Array(n) while (n--) { u8arr[n] = bstr.charCodeAt(n) } return new File([u8arr], filename, { type: mime }) }, // 将截取到第一帧的图片上传拿到url地址 async getVideoImgUrl(res) { const formData = new FormData() formData.append('file', res) formData.append('size', 100) formData.append('unit', 'M') const { data } = await worksList.uploadFile(formData) this.fileList.push(data.mapList[0]) this.form.imgPath = data.mapList[0].url }, handleRemove(file, fileList) { if (file.suffix === 'mp4') { this.uploadLimit = 20 this.imgType = 1 } if (file.status === 'success') this.fileList = fileList this.dialogUrl = null }, handlePreview(file) { if (this.videoSrc !== '') { this.dialogVideo = true this.dialogUrl = this.videoSrc } else { this.dialogUrl = file.url this.dialogImage = true } }, } } </script>