赞
踩
1、创建一个vue文件
<template> <!-- 阿里云上传视频 支持批量上传 --> <div id="uploadVideo"> <!-- 上传视频 dialog --> <el-dialog :title="$t('上傳視頻')" :visible.sync="isUploadVideo" center width="1000px" :show-close="false" :close-on-click-modal="false" :close-on-press-escape = 'false' > <div> <div class="upload-top"> <div class="upload-video-categoty"> <span>{{$t('视频分类',':')}}</span> <el-select :disabled="uploadDisabled" v-model="uploadParam.videoTypeId" :placeholder="$t('请选择视频分类')" > <el-option v-for="item in videoCategoryList" :key="item.videoManageCategoryId" :label="item.name" :value="item.videoManageCategoryId" ></el-option> </el-select> <span class="tip-text">{{$t('请先选择视频分类之后再上传视频')}}</span> </div> <el-upload :disabled="uploadDisabled || uploadParam.videoTypeId==''" class="upload-demo el-upload-dragger" :show-file-list="false" action="#" multiple :before-upload="beforeUploadVideo"> <i class="el-icon-upload"></i> <div class="el-upload__text"><em style="color: #c0c0c0">{{$t('点击上传')}}</em><div style="color: #c0c0c0;font-size: 12px">{{$t('只能上传MP4文件,且不超过2GB')}}</div></div> </el-upload> </div> <el-table :data="UploadVideoList" style="width: 100%;margin-top:20px" height="400" :header-cell-style="{background: '#f4f4f5'}" tooltip-effect="dark" border > <el-table-column prop="name" :label="$t('视频名称')"> <template slot-scope="scope"> <div class="video-message"> {{scope.row.file.name}} </div> </template> </el-table-column> <el-table-column prop="size" :label="$t('视频大小')"> <template slot-scope="scope"> <div>{{ scope.row.file.size | filterSize }}</div> </template> </el-table-column> <el-table-column prop="size" :label="$t('进度')"> <template slot-scope="scope"> <el-progress :text-inside="true" :stroke-width="26" :percentage="scope.row.progressBar" :format="format"></el-progress> </template> </el-table-column> <el-table-column prop="duration" :label="$t('操作')"> <template slot-scope="scope"> <span type="danger" class="ambow-btn-text-del" style="margin:0;padding:10px;" @click="onDelUploadVideoList(scope.row)" >{{$t('刪除')}}</span> </template> </el-table-column> </el-table> </div> <div slot="footer" class="dialog-footer"> <el-button @click="onDialogBtn()">{{$t('关闭')}}</el-button> <el-button style="margin-left:10px;" type="primary" @click="onStartUpload" :disabled="isStartUpload">{{ $t('开始上传') }}</el-button> </div> </el-dialog> </div> </template>
<script> import {uploadVideo} from "@/service/service"; var ossClient export default { name: "uploadVideo", data(){ return { uploadIndex:0,//批量上传时的索引 isStartUpload:true, UploadVideoList:[], uploadDisabled:false, uploadParam:{ firstImage: "", sourceFilesize: "", title: "", url: "", videoTimeSecond: "", videoTypeId: "" }, } }, props:['isUploadVideo','videoCategoryList','uploadAliyunUrl'], methods:{ //待上传视频列表--删除 onDelUploadVideoList(scope){ console.log(scope) if(this.uploadDisabled){ this.$message.error('视频正在上传中,禁止删除') return false }else if(scope.progressBar>0){ this.$message.error('视频已上传完成,无法删除') return false } this.$confirm($t('确定删除该数据','?'), $t('提示'), { confirmButtonText:$t('确定'), cancelButtonText:$t('取消'), type: 'warning' }).then(() => { this.UploadVideoList.forEach((item,index)=>{ if(scope.file.name==item.file.name){ console.log('111') this.UploadVideoList.splice(index,1) this.$message.success($t('删除成功')) } }) }).catch(() => { }); }, uploadVideo(){ console.log(this.uploadParam) uploadVideo(this.uploadParam).then((res)=>{ console.log(res) if(res.code==0){ if(this.uploadIndex+1==this.UploadVideoList.length){ this.uploadIndex+=1 this.uploadDisabled = false this.isStartUpload = true }else{ this.uploadIndex+=1 this.onUpload(this.UploadVideoList[this.uploadIndex],this.uploadIndex) } } }).catch((err)=>{ console.log(err) this.$message.error(err.msg) }) }, //上传失败时的回调 断点续传 restoreUpload(file,index){ let that = this window.axios.get(this.uploadAliyunUrl, {}).then((res)=>{ let ossInfo = res.data; ossClient = new OSS({ region: 'oss-cn-beijing', accessKeyId: ossInfo.accessKeyId, accessKeySecret: ossInfo.accessKeySecret, bucket: ossInfo.bucketName,// stsToken: ossInfo.securityToken, // endpoint: 'oss-accelerate.aliyuncs.com', secure: true }) const options = { progress:function(p,checkpoint){ that.UploadVideoList[index].progressBar = Number((p*100).toFixed(0)) }, checkpoint: that.tempCheckpoint, partSize: 1000 * 1024,//设置分片大小 timeout: 120000,//设置超时时间 }; ossClient.multipartUpload(that.name, file.file,options).then(res=>{ console.log('360-1',res) let url = ossClient.generateObjectUrl(that.name); console.log(url) that.uploadParam.firstImage = url+'?x-oss-process=video/snapshot,t_1000,m_fast' that.uploadParam.sourceFilesize = file.file.size that.uploadParam.title = file.file.name that.uploadParam.url = url that.uploadVideo() }).catch((err)=>{ if(err.name=='cancel'){ this.$message.success($t('已取消上传')) this.uploadDisabled = false this.UploadVideoList = [] }else{ this.restoreUpload(file) } }) }).catch((err)=>{ console.log(err) }) }, //点击开始上传 async onUpload(file,index){ function getDay(){ let time = new Date(), year = time.getFullYear(), month = time.getMonth() + 1 , day = time.getDate(), timeStem = time.getTime(); return `huanyujun/${year}${month}/${timeStem}.MP4` } this.name = getDay() this.uploadDisabled = true let that = this this.progressSeen = true //进度条显示 window.axios.get(this.uploadAliyunUrl, {}).then((res)=>{ let ossInfo = res.data; ossClient = new OSS({ region: 'oss-cn-beijing', accessKeyId: ossInfo.accessKeyId, accessKeySecret: ossInfo.accessKeySecret, bucket: ossInfo.bucketName,// stsToken: ossInfo.securityToken, // endpoint: 'oss-accelerate.aliyuncs.com', secure: true }) const options = { progress:function(p,checkpoint){ that.UploadVideoList[index].progressBar = Number((p*100).toFixed(0)) that.tempCheckpoint = checkpoint }, partSize: 1000 * 1024,//设置分片大小 timeout: 120000,//设置超时时间 }; ossClient.multipartUpload(that.name, file.file,options).then(res=>{ let url = ossClient.generateObjectUrl(that.name); that.uploadParam.firstImage = url+'?x-oss-process=video/snapshot,t_1000,m_fast' that.uploadParam.sourceFilesize = file.file.size that.uploadParam.title = file.file.name that.uploadParam.url = url that.uploadVideo() }).catch((err)=>{ if(err.name=='cancel'){ this.$message.success($t('已取消上传')) this.uploadDisabled = false }else{ that.restoreUpload(file,index) } }) }).catch((err)=>{ console.log(err) }) }, //进度条 format(percentage) { return percentage === 100 ? $t('上传完成') : `${percentage}%`; }, //上传验证 beforeUploadVideo(file){ // console.log(file.size) // console.log(file.size/1024/1024/1024) // console.log(1024*1024*1024*2) if(file.size/1024/1024/1024 > 2){ this.$message.error($t('视频过大,请进行压缩后上传')); return false } if(file.name.length>=100){ this.$message.error('视频名称过长'); return false; } if(this.uploadParam.videoTypeId==''){ this.$message.error('请先选择视频分类'); return false; } if (['video/mp4'].indexOf(file.type) == -1) { this.$message.error('请上传正确的视频格式'); return false; } let videFile = { file:file, progressBar:0 } this.UploadVideoList.push(videFile) this.isStartUpload = false console.log(this.UploadVideoList) }, //待上传视频列表--开始上传 onStartUpload(){ if(this.UploadVideoList.length==0){ this.$message.error($t('请选择上传的视频')) return false } // console.log(this.UploadVideoList[0].file); // return this.onUpload(this.UploadVideoList[this.uploadIndex],this.uploadIndex) this.isStartUpload = true // this.UploadVideoList.forEach((item,index)=>{ // console.log(item) // this.onUpload(item,index) // }) }, //关闭弹出框 onDialogBtn(){ if(this.uploadDisabled>0){ ossClient.cancel(); } this.uploadIndex = 0 this.uploadDisabled = false this.UploadVideoList = [] this.$emit('onDialogBtn') }, } } </script>
<style scoped> .upload-top{ width: 100%; height: 100%; text-align: center; } /deep/ .el-upload-dragger{ width: 950px !important; height: 125px !important; } /deep/ .el-icon-upload{ margin: 10px 0 16px; } .upload-video-categoty{ text-align: left; margin-bottom: 10px; display: flex; align-items: center; } .video-m3u8{ width: 50%; height: 50%; position: fixed; top: 200px; left: 200px; } /deep/.el-upload{ width: 100% !important; } .tip-text{ margin-left: 10px; color: #f56c6c; } </style>
2、在需要的组件中引用,并且传递需要的参数
import uploadVideos from './uploadVideo'
<uploadVideos :uploadAliyunUrl="'https://open-api.ambow.com/storage/api/v1/auth/ALIYUN/ambow/agora'" :isUploadVideo="isUploadVideo" :videoCategoryList="videoCategoryList" @onDialogBtn="onDialogBtn"></uploadVideos>
data(){
return {
isUploadVideo:false,
//视频分类
videoCategoryList:[],
}
}
onDialogBtn(){
this.isUploadVideo = false
this.getVideoList()
},
简单说一下注意的地方:
1、由于此次阿里云上传的是视频,所以会出现视频过大,导致阿里云的backName过期,上传不成功,这里需要用到阿里云的断点续传,在第一次上传时,创建一个全局变量ossClient来保存,在失败的时候调用,直到成功
2.有些视频需要封面设置,而阿里云也提供了相关方法,返回的url+‘?x-oss-process=video/snapshot,t_1000,m_fast’便是视频首图
const options = { progress:function(p,checkpoint){ that.UploadVideoList[index].progressBar = Number((p*100).toFixed(0)) that.tempCheckpoint = checkpoint }, partSize: 1000 * 1024,//设置分片大小 timeout: 120000,//设置超时时间 }; ossClient.multipartUpload(that.name, file.file,options).then(res=>{ let url = ossClient.generateObjectUrl(that.name); that.uploadParam.firstImage = url+'?x-oss-process=video/snapshot,t_1000,m_fast' that.uploadParam.sourceFilesize = file.file.size that.uploadParam.title = file.file.name that.uploadParam.url = url that.uploadVideo() }).catch((err)=>{ if(err.name=='cancel'){ this.$message.success($t('已取消上传')) this.uploadDisabled = false }else{ that.restoreUpload(file,index) } })
progress的回调中,p代表进度条,checkpoint代表上传进度,声明两个变量将其保存下来
const options = {
progress:function(p,checkpoint){
that.UploadVideoList[index].progressBar = Number((p*100).toFixed(0))
},
checkpoint: that.tempCheckpoint,
partSize: 1000 * 1024,//设置分片大小
timeout: 120000,//设置超时时间
};
在失败上传的方法中,需要重新读取阿里云地址,更新backName,然后将保存的progressBar 、checkpoint复制上去变实现了断点续传或者说分片上传
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。