这段时间项目里有一个上传视频到阿里云的功能是我来负责写的,之前一直没有写过这种功能,感觉很难的亚子,但是后来仔细研究了一遍发现也没想象中那么难,最后经过不懈的努力也算是搞出来了哈哈哈,开心坏我了。搞出这个功能真的也是学习到了很多东西,所以就来这里记录一下啦。也有同样需求的兄弟姐妹们希望可以帮到你们一点点嘻嘻,如果有更简单轻便的方法或哪里需要改进的地方也请大家多多指教呦
我用的就是 vue+element 写的
阿里云给我们提供了客户端上传的SDK
使用JavaScript上传SDK.
这个页面从头到尾过一遍就能了解个大概了
细心的小伙伴在下载SDK的时候就会发现有demo可以看哈哈哈
阿里云真的绝绝子啊!!! 直接有代码可以抄,这还不Ctrl+C / Ctrl+V 安排上
让后台给出 获取上传凭证和地址 接口 一对接,ok,功能完成!!!
哈哈哈哈,其实没这么简单,
我开始真单纯的以为就这样就结束了,然而被告知需要批量上传的时候我都石化了,阿里云也没批量上传的代码让我来抄,
害,然而又有什么办法呢,写呗,
因为我写的页面就是纯单个上传的那种,批量删除要显示成列表形式的,所以之前写的页面几乎不能用了,然后我就只能重新搞一个页面再写了,当然上传方法还是用的阿里云上传的那个方法
因为单个上传的页面代码啥的都已经让我给删了所以下面就直接分享批量上传的代码和页面了
首先来看一下上传视频的页面吧
demo里面那些按钮还是能继续用的
然后看代码
html
页面样式这些感觉自己公司的要求或者自己的喜好来写就好了
JS
// 添加视频文件 fileChange (e) { console.log(e.target.files); this.files = e.target.files if (!this.files) { return this.$message.warning("选择需要上传的视频") } var userData = '{"Vod":{}}' if (this.uploader) { this.uploader.stopUpload() this.authProgress = 0 this.statusText = "" } this.uploader = this.createUploader() for (let i = 0; i < this.files.length; i++) { let url = URL.createObjectURL(this.files[i]); let audioElement = new Audio(url); setTimeout(() => { this.videomsg = { title: this.files[i].name.substring(0, this.files[i].name.indexOf('.')), fileName: this.files[i].name, type: 0, size: this.files[i].size, seconds: audioElement.duration, } //因为 获取上传地址和凭证接口需要很多参数,而这样列表形式的参数传的时候不太好搞,我在这里直接给他加到file里面了,一会再上传的方法里可以直接获取当前上传文件的所有参数 this.files[i].obj = this.videomsg //addFile是添加文件的方法(这些null,null,null我的不知道什么鬼,一度尝试用他们来把参数加进去可惜都不行,前两个是报错,后一个可以没报错,传进去是在一个object对象里面,可以我捣鼓了半天还是不行) this.uploader.addFile(this.files[i], null, null, null, userData)
this.videoList.push(this.videomsg) }, 500) } this.uploadDisabled = false this.pauseDisabled = true this.resumeDisabled = true },
下面这段代码跟上面的这一段是一个方法,只是变更了一下传递参数的方式,因项目需求后期修改了一下
// 添加视频文件
fileChange (e) {
if (!e.target.files) {
return this.$message.warning("选择需要上传的视频")
}
var userData = '{"Vod":{}}'
if (this.uploader) {
this.uploader.stopUpload()
this.authProgress = 0
this.statusText = ""
}
this.uploader = this.createUploader()
e.target.files.forEach((item, index) => {
let url = URL.createObjectURL(item);
let audioElement = new Audio(url);
setTimeout(() => {
this.videomsg = {
title: item.name.substring(0, item.name.indexOf('.')),
fileName: item.name,
type: 0,
size: item.size,
seconds: audioElement.duration,
}
this.compare(this.videoList, this.videomsg)
this.videoList.forEach(item => {
if (!item.tagItems) {
item.tagItems = []
}
})
item.obj = this.videomsg
this.files.push(item)
}, 500)
})
setTimeout(() => {
for (let i = 0; i < this.files.length; i++) {
this.uploader.addFile(this.files[i], null, null, null, userData)
}
}, 600);
this.uploadDisabled = false
this.pauseDisabled = true
this.resumeDisabled = true
},
createUploader () { let self = this let uploader = new AliyunUpload.Vod({ timeout: 90000,//这个是上传失效时间 partSize: 1048576, parallel: self.files.length, retryCount: 3, retryDuration: 2, region: 'cn-beijing',//填写自己阿里云服务器的region userId: '275487806961125824', // 添加文件成功 addFileSuccess: function (uploadInfo) { self.uploadDisabled = false self.resumeDisabled = false self.clearDisabled = false self.statusText = '添加文件成功,等待上传...'
// self.updateState = true // self.updateText = '文件已添加成功,还未上传,关闭窗口后之前操作都将失效,是否确认关闭?' }, // 开始上传 onUploadstarted: function (uploadInfo) { // var list = self.uploader.listFiles() // for (let i = 0; i < list.length; i++) { // console.log("上传列表", list[i]); // } if (!uploadInfo.videoId) { console.log("获取上传凭证", uploadInfo); //这个调后台给的 获取上传地址和凭证接口 addMediaResource(uploadInfo.file.obj).then((result) => { // console.log(result); let uploadAuth = result.uploadSecurity.uploadAuth let uploadAddress = result.uploadSecurity.uploadAddress let videoId = result.uploadSecurity.videoId //这个是阿里云上传的方法(阿里云会自定依次上传你选择的多个视频的,不需要循环或者什么的) self.uploader.setUploadAuthAndAddress(uploadInfo, uploadAuth, uploadAddress, videoId); self.uploadIds.push(result.id) //因后台上传会很占用带宽,所以没用后台的上传接口 //让后端给一个更新阿里云数据的接口,上传结束后在列表页面调用一下就ok了(不是指上传列表哦) }).catch((err) => { let fileName = err.message.slice(9) for (let i = 0; i < self.videoList.length; i++) { if (fileName == self.videoList[i].title) { self.delvideo(self.videoList[i], i) } } const h = self.$createElement; self.$notify({ title: '提示', message: h('i', { style: 'color: teal' }, '列表已存在' + fileName + '文件,无法再次上传,点击 恢复上传 按钮继续上传其他文件'), duration: 0 }); self.uploader.stopUpload() self.authProgress = 0 self.statusText = "" self.pauseDisabled = true }); } else { console.log("刷新上传凭证"); // 如果videoId有值,根据videoId刷新上传凭证(https://help.aliyun.com/document_detail/55408.html) refreshMediaResource(uploadInfo.videoId).then((result) => { let uploadAuth = result.uploadAuth let uploadAddress = result.uploadAddress let videoId = result.videoId self.uploader.setUploadAuthAndAddress(uploadInfo, uploadAuth, uploadAddress, videoId) }).catch((err) => { console.log(err); }); } }, // 文件上传成功 onUploadSucceed: function (uploadInfo) { console.log('文件上传成功', uploadInfo); // console.log("onUploadSucceed: " + uploadInfo.file.name + ", endpoint:" + uploadInfo.endpoint + ", bucket:" + uploadInfo.bucket + ", object:" + uploadInfo.object) self.statusText = '文件上传成功!' self.file = uploadInfo.file.name }, // 文件上传失败 onUploadFailed: function (uploadInfo, code, message) { console.log('文件上传失败', uploadInfo); // console.log("onUploadFailed: file:" + uploadInfo.file.name + ",code:" + code + ", message:" + message) self.statusText = '文件上传失败!' }, // 取消文件上传 onUploadCanceled: function (uploadInfo, code, message) { console.log('文件已暂停上传', uploadInfo); // console.log("Canceled file: " + uploadInfo.file.name + ", code: " + code + ", message:" + message) self.statusText = '文件已暂停上传' }, // 文件上传进度,单位:字节,可以在这个函数中拿到上传进度并显示在页面上 onUploadProgress: function (uploadInfo, totalSize, progress) { console.log('文件上传中', uploadInfo); // console.log("onUploadProgress:file:" + uploadInfo.file.name + ", fileSize:" + totalSize + ", percent:" + Math.ceil(progress * 100) + "%") let progressPercent = Math.ceil(progress * 100) self.authProgress = progressPercent self.file = uploadInfo.file.name self.statusText = '文件上传中' self.updateState = true self.updateText = '文件上传中,关闭窗口上传文件将会出现异常,请勿关闭窗口!!!' }, // 上传凭证超时 onUploadTokenExpired: function (uploadInfo) { console.log('文件超时', uploadInfo); // 上传大文件超时, 如果是上传方式一即根据 UploadAuth 上传时 // 需要根据 uploadInfo.videoId 调用刷新视频上传凭证接口(https://help.aliyun.com/document_detail/55408.html)重新获取 UploadAuth // 然后调用 resumeUploadWithAuth 方法 refreshMediaResource(uploadInfo.videoId).then((data) => { let uploadAuth = data.UploadAuth uploader.resumeUploadWithAuth(uploadAuth) }).catch((err) => { console.log(err); }); self.statusText = '文件超时...' }, // 全部文件上传结束 onUploadEnd: function (uploadInfo) { console.log('文件上传完毕uploaded all the files'); self.statusText = '文件上传完毕' self.$emit("addMediaResource", self.uploadIds); self.updateState = false self.handleClose() } }) return uploader },
好的,批量上传功能完成,
我原来还以为上传多个需要循环什么的,死活搞不好各种百度搜,后来也在一个大佬博客下发现只要在this.uploader.addFile()那里把文件循环加入就好了,其他的什么都不要管,new AliyunUpload.Vod(){}方法会一次帮你上传的,进度条也只需一条就好了
感觉自己又提升了呢,加油加油加油