当前位置:   article > 正文

【上传文件】基于阿里云的视频点播VOD、对象存储OSS实现音视频图片等文件上传_oss vod

oss vod

一、效果演示

a.测试界面初始化

b.点击【上传视频】

c.点击【开始上传】

d.点击【上传音频】选择音频之后点击【开始上传】

c.点击【上传图片】,注意图片上传为单按钮,选择文件之后自动完成上传

d.点击【确定】来获取以上几个上传文件成功之后返回的最关键的key值

注:其中音视频我们取其videoId,图片取url

 

二、测试页面代码

此处,先展示上方测试页面对已封装好的上传组件的引用代码,如下:

  1. <template>
  2. <div>
  3. <h5>上传视频组件测试</h5>
  4. <div>
  5. <video-upload v-model="uploadVideoId"></video-upload>
  6. </div>
  7. <h5>上传音频组件测试</h5>
  8. <div>
  9. <audio-upload v-model="uploadAudioId"></audio-upload>
  10. </div>
  11. <h5>上传图片组件测试</h5>
  12. <div>
  13. <img-upload v-model="uploadImgUrl"></img-upload>
  14. </div>
  15. <h5>获取上传成功的值</h5>
  16. <el-button size="small" type="primary" @click="getVal">确定</el-button>
  17. <div class="msgContent" v-if="msg" v-html="msg"></div>
  18. </div>
  19. </template>
  20. <script>
  21. import videoUpload from '@/components/videoUpload'
  22. import audioUpload from '@/components/audioUpload'
  23. import imgUpload from '@/components/imgUpload'
  24. export default {
  25. data() {
  26. return {
  27. uploadVideoId: '',
  28. uploadAudioId: '',
  29. uploadImgUrl: '',
  30. msg: ''
  31. }
  32. },
  33. components: {
  34. videoUpload,
  35. audioUpload,
  36. imgUpload
  37. },
  38. methods: {
  39. getVal() {
  40. this.msg = `
  41. this.uploadVideoId is :
  42. <br>
  43. ${this.uploadVideoId}
  44. <br>
  45. this.uploadAudioId is :
  46. <br>
  47. ${this.uploadAudioId}
  48. <br>
  49. this.uploadImgUrl is :
  50. <br>
  51. ${this.uploadImgUrl}`
  52. }
  53. }
  54. }
  55. </script>
  56. <style lang="less" scoped>
  57. h5 {
  58. margin: 36px 0 12px 0;
  59. }
  60. .msgContent {
  61. margin-top: 10px;
  62. font-size: 14px;
  63. color: #606266;
  64. line-height: 24px;
  65. }
  66. </style>

主要实现的上传组件为图片上传(imgUpload)、视频上传(videoUpload)、音频上传(audioUpload),其中图片上传的组件是基于阿里云对象存储(OSS) 来实现的,而音视频上传都是基于阿里云视频点播(VOD)实现的,具体实现方式见下文。

 

三、图片上传

官方文档介绍:对象存储OSS-SDK参考-Node.js上传文件

相对音视频的上传,图片上传的方式会比较简单,我们先介绍图片上传组件的实现方式吧。首先我们参考的是node.js环境下的上传文件最简单的方式,即通过put接口来上传一个本地文件到OSS,至于流式上传、分片上传、断点上传等相对较复杂的上传方式此处不予介绍,反正举一反三,都是差不多的套路。

第一步,安装SDK

注:支持的Node.js版本: Node.js >= 8.0.0 如果需要在 Node.js < 8 的环境中使用,请使用 ali-oss 4.x版本。

npm install ali-oss

第二步,使用SDK

通过初始化一个client,然后调用其put方法即可。

官网给出的关键代码:

  1. let OSS = require('ali-oss')
  2. let client = new OSS({
  3. region: '<Your region>',
  4. accessKeyId: '<Your AccessKeyId>',
  5. accessKeySecret: '<Your AccessKeySecret>',
  6. bucket: 'Your bucket name'
  7. });
  8. async function put () {
  9. try {
  10. let result = await client.put('object-name', 'local-file');
  11. console.log(result);
  12. } catch (e) {
  13. console.log(er);
  14. }
  15. }
  16. put();

结合我们的实际应用场景,我们在new OSS的时候会多传一个stsToken参数,stsToken的值由后端接口给我们提供,此处我们取的是后端返回的securityToken,其作用主要用于进行临时授权访问,可以参考官方文档:使用STS访问

另外,基于这位SDK大兄弟的功能我们结合产品需求实现了以下几点额外功能:

a、不要丑陋的原生input按钮,自定义上传按钮;

b、上传限制仅图片格式;

c、上传成功之后展示已上传的缩略图;

d、组件的v-model值用于存储图片上传成功后的url。

OK,然后我们欣赏一下 imgUpload.vue 的实现代码:

  1. <template>
  2. <div>
  3. <input type="file" v-show="false" accept="image/*" ref="input" @change="fileChange">
  4. <!-- 通过$refs操作input的点击事件,调起文件选择 -->
  5. <el-button size="small" type="success" @click="$refs.input.click()">
  6. 上传图片
  7. </el-button>
  8. <img v-if="imgUrl" class="imgShow" :src="imgUrl"/>
  9. </div>
  10. </template>
  11. <script>
  12. export default {
  13. props: {
  14. value: {
  15. type: String,
  16. default: ''
  17. }
  18. },
  19. data() {
  20. return {
  21. uploadFile: null,
  22. imgUrl: ''
  23. }
  24. },
  25. watch: {
  26. imgUrl: function (val) {
  27. if (val !== this.value) {
  28. this.$emit('input', val)
  29. }
  30. }
  31. },
  32. methods: {
  33. fileChange() {
  34. if (!event.target.files[0]) {
  35. return false
  36. }
  37. console.log(event.target.files[0])
  38. if (!event.target.files[0].type.match('image.*')) {
  39. this.$message.error('请选择图片')
  40. return false
  41. }
  42. this.uploadFile = event.target.files[0]
  43. this.$apis.getImageUploadInfo({'fileName': this.uploadFile.name}).then(res => {
  44. if (res.code === '2000') {
  45. let objectName = res.data.key
  46. let OSS = require('ali-oss')
  47. let client = new OSS({
  48. region: res.data.regionId,
  49. accessKeyId: res.data.accessKeyId,
  50. accessKeySecret: res.data.accessKeySecret,
  51. stsToken: res.data.securityToken,
  52. bucket: res.data.bucket
  53. })
  54. const put = async() => {
  55. try {
  56. let result = await client.put(objectName, this.uploadFile)
  57. console.log(result)
  58. if (result.res.statusCode === 200) {
  59. this.$message.success('上传成功')
  60. this.imgUrl = result.url
  61. } else {
  62. this.$message.success('上传失败')
  63. this.imgUrl = ''
  64. }
  65. } catch (e) {
  66. this.$message.error(e)
  67. console.log(e)
  68. }
  69. }
  70. put()
  71. } else {
  72. this.$message.error(res.message)
  73. }
  74. }).catch(error => {
  75. this.$message.error(error)
  76. })
  77. }
  78. }
  79. }
  80. </script>
  81. <style lang="less" scoped>
  82. .imgShow {
  83. display: block;
  84. height: 100px;
  85. margin: 12px 0;
  86. }
  87. </style>

上传成功之后的文件可以去阿里云的对象存储控制台查看,传送门:https://oss.console.aliyun.com/

后台截图:

 

四、视频上传

官方文档介绍:视频点播-客户端SDK-上传SDK-JavaScript上传SDK

其实基于上面那位OSS大兄弟的强大存储功能我们也可以实现视频的上传存储,但是需求方对于视频的处理要求比较过分,哦不,是比较精致。所以,我们采用阿里云视频点播来实现对视频的上传与播放。阿里云视频点播(VOD)是集音视频采集、编辑、上传、自动化转码处理、媒体资源管理、分发加速、视频播放于一体的一站式音视频点播解决方案。知道它的厉害了吧~

第一步,安装SDK

相对于OSS大兄弟,VOD的安装比较土了,不,是比较简单了,在我们的页面上引入三个JS脚本,脚本下载:视频点播-客户端SDK下载

引入代码,官方demo:

  1. <!-- IE需要es6-promise -->
  2. <script src="../lib/es6-promise.min.js"></script>
  3. <script src="../lib/aliyun-oss-sdk4.13.2.min.js"></script>
  4. <script src="../aliyun-vod-upload-sdk1.3.1.min.js"></script>

实际应用中,我们会在index.html的屁股后面引入这三位大兄弟,如下:

  1. <body>
  2. <div id="app"></div>
  3. <!-- built files will be auto injected -->
  4. <!-- 引入第三方库-阿里云视频上传 start-->
  5. <script src="./static/lib/es6-promise.min.js"></script>
  6. <script src="./static/lib/aliyun-oss-sdk-5.2.0.min.js"></script>
  7. <script src="./static/lib/aliyun-upload-sdk-1.4.0.min.js"></script>
  8. <!-- 引入第三方库-阿里云视频上传 end-->
  9. </body>

ps:为什么不放<head>里边引入,我就不解释了。

第二步,使用SDK

使用过程中,推荐参考上方下载好的示例代码,里边注释给的也很清楚,相比较官网文档的话会更好理解。

官网给出的关键代码:

  1. var uploader = new AliyunUpload.Vod({
  2. //分片大小默认1M,不能小于100K
  3. partSize: 1048576,
  4. //并行上传分片个数,默认5
  5. parallel: 5,
  6. //网络原因失败时,重新上传次数,默认为3
  7. retryCount: 3,
  8. //网络原因失败时,重新上传间隔时间,默认为2秒
  9. retryDuration: 2,
  10. // 开始上传
  11. 'onUploadstarted': function (uploadInfo) {
  12. log("onUploadStarted:" + uploadInfo.file.name + ", endpoint:" + uploadInfo.endpoint + ", bucket:" + uploadInfo.bucket + ", object:" + uploadInfo.object);
  13. //上传方式1, 需要根据uploadInfo.videoId是否有值,调用点播的不同接口获取uploadauth和uploadAddress,如果videoId有值,调用刷新视频上传凭证接口,否则调用创建视频上传凭证接口
  14. // uploader.setUploadAuthAndAddress(uploadInfo, uploadAuth, uploadAddress,videoId);
  15. //上传方式2
  16. // uploader.setSTSToken(uploadInfo, accessKeyId, accessKeySecret,secretToken);
  17. }
  18. // 文件上传成功
  19. 'onUploadSucceed': function (uploadInfo) {
  20. log("onUploadSucceed: " + uploadInfo.file.name + ", endpoint:" + uploadInfo.endpoint + ", bucket:" + uploadInfo.bucket + ", object:" + uploadInfo.object);
  21. },
  22. // 文件上传失败
  23. 'onUploadFailed': function (uploadInfo, code, message) {
  24. log("onUploadFailed: file:" + uploadInfo.file.name + ",code:" + code + ", message:" + message);
  25. },
  26. // 文件上传进度,单位:字节
  27. 'onUploadProgress': function (uploadInfo, totalSize, loadedPercent) {
  28. log("onUploadProgress:file:" + uploadInfo.file.name + ", fileSize:" + totalSize + ", percent:" + Math.ceil(loadedPercent * 100) + "%");
  29. },
  30. // 上传凭证超时
  31. 'onUploadTokenExpired': function (uploadInfo) {
  32. console.log("onUploadTokenExpired");
  33. //上传方式1 实现时,根据uploadInfo.videoId调用刷新视频上传凭证接口重新获取UploadAuth
  34. // uploader.resumeUploadWithAuth(uploadAuth);
  35. // 上传方式2 实现时,从新获取STS临时账号用于恢复上传
  36. // uploader.resumeUploadWithSTSToken(accessKeyId, accessKeySecret, secretToken, expireTime);
  37. },
  38. //全部文件上传结束
  39. 'onUploadEnd':function(uploadInfo){
  40. log("onUploadEnd: uploaded all the files");
  41. }
  42. });

从例子中可知,这位大兄弟有两种上传方式:VodMode 、STSMode,使用上两者需要的上传凭证是不同的,接下来我们介绍的是STS模式,该模式下需要后端给我们的值有:securityToken、accessKeyId、accessKeySecret

另外,基于这位SDK大兄弟的功能我们结合产品需求实现了以下几点额外功能:

a、不要丑陋的原生input按钮,自定义上传按钮;

b、上传限制仅视频格式及视频大小;

c、上传过程中显示进度条效果;

d、组件的v-model值用于存储视频上传成功后的videoId。

OK,然后我们欣赏一下 videoUpload.vue 的实现代码:

  1. <template>
  2. <div>
  3. <input type="file" v-show="false" accept="video/*" ref="input" @change="fileChange">
  4. <el-button size="small" type="primary" @click="$refs.input.click()" :disabled="disableUpload">
  5. 上传视频
  6. </el-button>
  7. <el-button style="margin-left: 10px;" size="small" type="success" @click="uploader.startUpload()" :disabled="disableSubmit">
  8. 开始上传
  9. </el-button>
  10. <div class="el-upload__tip">视频文件仅限5分钟以内,大小不超过150M</div>
  11. <template v-if="uploadFile && uploadFile.name">
  12. <div class="el-upload__tip">{{uploadFile.name}}</div>
  13. <el-progress style="width:200px;" :percentage="percentage" :status="percentage === 100 ? 'success' : ''"></el-progress>
  14. </template>
  15. </div>
  16. </template>
  17. <script>
  18. export default {
  19. props: {
  20. value: {
  21. type: String,
  22. default: ''
  23. }
  24. },
  25. data() {
  26. return {
  27. securityToken: '',
  28. accessKeyId: '',
  29. accessKeySecret: '',
  30. disableUpload: false,
  31. disableSubmit: true,
  32. uploadFile: null,
  33. uploader: null,
  34. callback: null,
  35. videoId: '',
  36. percentage: 0
  37. }
  38. },
  39. watch: {
  40. videoId: function (val) {
  41. if (val !== this.value) {
  42. this.$emit('input', val)
  43. }
  44. }
  45. },
  46. methods: {
  47. fileChange() {
  48. if (!event.target.files[0]) {
  49. return false
  50. }
  51. console.log(event.target.files[0])
  52. if (!event.target.files[0].type.match('video.*')) {
  53. this.$message.error('请选择视频文件')
  54. return false
  55. }
  56. this.uploadFile = event.target.files[0]
  57. this.percentage = 0
  58. // 上传文件的size的单位为 字节(b)
  59. // 150兆字节(mb) = 157286400字节(b)
  60. if (this.uploadFile.size <= 157286400) {
  61. this.getAuth(() => {
  62. // 给uploader大佬addFile
  63. this.getUploder()
  64. // 以下三个参数默认为空
  65. // var endpoint = ''
  66. // var bucket = ''
  67. // var objectPre = ''
  68. // if(objectPre)
  69. // {
  70. // object = objectPre +"/"+ event.target.files[i].name
  71. // }
  72. // STS的上传方式,需要在userData里指定Title
  73. var userData = '{"Vod":{"StorageLocation":"","Title":"' + this.uploadFile.name + '","Description":"默认描述信息暂无","CateId":"19","Tags":"测试视频"}}'
  74. this.uploader.addFile(this.uploadFile, '', '', '', userData)
  75. console.log(`add file: ${this.uploadFile.name}`)
  76. this.disableSubmit = false
  77. })
  78. } else {
  79. this.disableSubmit = true
  80. this.$message.error('上传的文件大小超过150M,请重新上传')
  81. }
  82. },
  83. getAuth(callback) {
  84. // 获取上传凭证
  85. this.$apis.getVideoUploadAuth().then(res => {
  86. if (res.code === '2000') {
  87. this.securityToken = res.data.securityToken
  88. this.accessKeyId = res.data.accessKeyId
  89. this.accessKeySecret = res.data.accessKeySecret
  90. callback()
  91. } else {
  92. this.$message.error(res.message)
  93. }
  94. }).catch(error => {
  95. this.$message.error(error)
  96. })
  97. },
  98. getUploder() {
  99. let _this = this
  100. /* eslint-disable no-undef */
  101. _this.uploader = new AliyunUpload.Vod({
  102. // 文件上传失败
  103. 'onUploadFailed': function (uploadInfo, code, message) {
  104. _this.$message.error(`文件上传失败:${message}`)
  105. console.log(`onUploadFailed: file:${uploadInfo.file.name},code:${code}, message:${message}`)
  106. _this.disableSubmit = true
  107. _this.disableUpload = false
  108. },
  109. // 文件上传完成
  110. 'onUploadSucceed': function (uploadInfo) {
  111. console.log(uploadInfo)
  112. // console.log(`onUploadSucceed: ${uploadInfo.file.name}, endpoint:${uploadInfo.endpoint}, bucket:${uploadInfo.bucket}, object:${uploadInfo.object}`)
  113. _this.videoId = uploadInfo.videoId
  114. _this.$message.success('文件上传成功')
  115. _this.disableSubmit = true
  116. _this.disableUpload = false
  117. },
  118. // 文件上传进度
  119. 'onUploadProgress': function (uploadInfo, totalSize, loadedPercent) {
  120. _this.percentage = +(loadedPercent * 100).toFixed(0)
  121. // console.log(`onUploadProgress:file:${uploadInfo.file.name}, fileSize:${totalSize}, percent:${(loadedPercent * 100.00).toFixed(2)}%`)
  122. },
  123. // STS临时账号会过期,过期时触发函数
  124. 'onUploadTokenExpired': function (uploadInfo) {
  125. console.log('onUploadTokenExpired STS临时账号过期了')
  126. // 实现时,从新获取STS临时账号用于恢复上传
  127. // uploader.resumeUploadWithSTSToken(accessKeyId, accessKeySecret, securityToken, expireTime)
  128. },
  129. onUploadCanceled: function(uploadInfo) {
  130. console.log(`onUploadCanceled:file:${uploadInfo.file.name}`)
  131. },
  132. // 开始上传
  133. 'onUploadstarted': function (uploadInfo) {
  134. var accessKeyId = _this.accessKeyId
  135. var accessKeySecret = _this.accessKeySecret
  136. var securityToken = _this.securityToken
  137. _this.uploader.setSTSToken(uploadInfo, accessKeyId, accessKeySecret, securityToken)
  138. console.log(`onUploadStarted:${uploadInfo.file.name},endpoint:${uploadInfo.endpoint}, bucket:${uploadInfo.bucket}, object:${uploadInfo.object}`)
  139. },
  140. 'onUploadEnd': function(uploadInfo) {
  141. console.log('onUploadEnd: uploaded all the files')
  142. }
  143. })
  144. }
  145. }
  146. }
  147. </script>

上传成功之后的文件可以去阿里云的视频点播控制台查看,传送门:https://vod.console.aliyun.com/

后台截图:

 

五、音频上传

音频上传实际上用的就是视频上传那套逻辑,代码也是ctrl+c、ctrl+v过去的,主要改动:

a、把按钮文字“上传视频”改为“上传音频”

b、限制视频格式改为限制音频.mp3格式

<input type="file" v-show="false" accept="video/*" ref="input" @change="fileChange">

改为

<input type="file" v-show="false" accept="audio/mpeg" ref="input" @change="fileChange">

c、js部分

  1. if (!event.target.files[0].type.match('video.*')) {
  2. this.$message.error('请选择视频文件')
  3. return false
  4. }

改为

  1. if (!event.target.files[0].type.match('audio.*')) {
  2. this.$message.error('请选择音频文件')
  3. return false
  4. }

其它都和视频上传一样使用,包括上传成功之后存的地方也是一样的,有图有真相:

 

完。

------------------------------------------------------------------

2018.12.22 补充更新

如果是移动端应用,需要与客户端通信获取到的是base64的图片资源,如何进行文件转换并上传呢?

请出门右转>>>js接收客户端base64图片转换Blob

------------------------------------------------------------------

2018.12.26 补充更新

本文只是简单地演示了一下上传阿里云的一些功能,具体交互有待优化。

以图片上传为例,可以出门左转>>【上传组件优化】el-upload组件结合上传阿里云OSS实现更优交互

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/246037
推荐阅读
相关标签
  

闽ICP备14008679号