new_video.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  1. <template>
  2. <div class="box">
  3. <div class="add" @click="add()">+</div>
  4. <input id="video" ref="add" type="file" accept="video/*" @change="afterRead2()" hidden="true" />
  5. <div class="tip">说明:当此最多允许传1G视频,推荐采用MP4、flv格式,可缩短审核转码耗时</div>
  6. <van-overlay :show="videoShow" @click="closeVideo">
  7. <div class="wrapper flex">
  8. <video id="video-play " :src="src" ref="videos" controls @click.stop></video>
  9. <el-button
  10. class="btn"
  11. type="primary"
  12. :loading="btn.loading"
  13. @click="getAuth()"
  14. @click.stop
  15. >{{btn.title}}</el-button>
  16. </div>
  17. </van-overlay>
  18. </div>
  19. </template>
  20. <script>
  21. import "@/assets/css/common.css";
  22. import Vue from "vue";
  23. import { Overlay } from "vant";
  24. import { Button } from "element-ui";
  25. import { Uploader, Icon, Toast } from "vant";
  26. export default {
  27. layout: "opacity_header",
  28. async asyncData({ $axios, params, req }) {
  29. return {
  30. title: `选择视频-程序员客栈`
  31. };
  32. },
  33. head() {
  34. return {
  35. title: this.title,
  36. script: [
  37. {
  38. src: "https://hm.baidu.com/hm.js?18455f493c982100e5a82ec978a8d06e"
  39. },
  40. {
  41. src: "https://stacdn.proginn.com/quan_v3/aliyun-upload-sdk/lib/es6-promise.min.js"
  42. },
  43. {
  44. src: "https://stacdn.proginn.com/quan_v3/aliyun-upload-sdk/lib/aliyun-oss-sdk-5.3.1.min.js"
  45. },
  46. {
  47. src:"https://stacdn.proginn.com/quan_v3/aliyun-upload-sdk/aliyun-upload-sdk-1.5.0.min.js"
  48. }
  49. ]
  50. };
  51. },
  52. data() {
  53. return {
  54. src: "",
  55. fileList: [],
  56. videoShow: false,
  57. uploadInfo: {},
  58. file: null,
  59. fileName: null,
  60. btn: {
  61. loading: false,
  62. title: "开始上传"
  63. }
  64. };
  65. },
  66. created() {
  67. this.needLogin();
  68. },
  69. methods: {
  70. //开始上传,
  71. getAuth() {
  72. let that = this;
  73. that.btn.loading = true;
  74. that.btn.title = "读取文件";
  75. this.$axios
  76. .$post("/api/jishuquan/get_upload_token", {
  77. file_name: "test.mp4"
  78. })
  79. .then(res => {
  80. console.log(res);
  81. that.uploadInfo = {
  82. uploadAuth: res.data.UploadAuth,
  83. uploadAddress: res.data.UploadAddress,
  84. videoId: res.data.VideoId
  85. };
  86. that.btn.title = "开始上传";
  87. that.uploadVideo();
  88. });
  89. },
  90. uploadVideo() {
  91. let userData = '{"Vod":{}}';
  92. let uploader = this.createUploader();
  93. uploader.addFile(this.file, null, null, null, userData);
  94. uploader.startUpload();
  95. },
  96. goCreate() {
  97. console.log("++++++++++++++", this.uploadInfo.videoId);
  98. this.$router.push({
  99. path: "/user/new_video_upload",
  100. query: { vid: this.uploadInfo.videoId }
  101. });
  102. },
  103. createUploader(type) {
  104. let self = this;
  105. let uploader = new AliyunUpload.Vod({
  106. timeout: 60000,
  107. partSize: 1048576,
  108. parallel: 5,
  109. retryCount: 3,
  110. retryDuration: 2,
  111. region: "cn-beijing",
  112. userId: "1402206442454882",
  113. enableUploadProgress: true,
  114. // 添加文件成功
  115. addFileSuccess: function(uploadInfo) {
  116. console.log("addFileSuccess: " + uploadInfo.file.name);
  117. },
  118. // 开始上传
  119. onUploadstarted: function(uploadInfo) {
  120. // 如果是 UploadAuth 上传方式, 需要调用 uploader.setUploadAuthAndAddress 方法
  121. // 如果是 UploadAuth 上传方式, 需要根据 uploadInfo.videoId是否有值,调用点播的不同接口获取uploadauth和uploadAddress
  122. // 如果 uploadInfo.videoId 有值,调用刷新视频上传凭证接口,否则调用创建视频上传凭证接口
  123. // 注意: 这里是测试 demo 所以直接调用了获取 UploadAuth 的测试接口, 用户在使用时需要判断 uploadInfo.videoId 存在与否从而调用 openApi
  124. // 如果 uploadInfo.videoId 存在, 调用 刷新视频上传凭证接口(https://help.aliyun.com/document_detail/55408.html)
  125. // 如果 uploadInfo.videoId 不存在,调用 获取视频上传地址和凭证接口(https://help.aliyun.com/document_detail/55407.html)
  126. // if (!uploadInfo.videoId) {
  127. // let createUrl =
  128. // 'https://demo-vod.cn-shanghai.aliyuncs.com/voddemo/CreateUploadVideo?Title=testvod1&FileName=aa.mp4&BusinessType=vodai&TerminalType=pc&DeviceModel=iPhone9,2&UUID=59ECA-4193-4695-94DD-7E1247288&AppVersion=1.0.0&VideoId=5bfcc7864fc14b96972842172207c9e6'
  129. // axios.get(createUrl).then(({
  130. // data
  131. // }) => {
  132. // let uploadAuth = data.UploadAuth
  133. // let uploadAddress = data.UploadAddress
  134. // let videoId = data.VideoId
  135. uploader.setUploadAuthAndAddress(
  136. uploadInfo,
  137. self.uploadInfo.uploadAuth,
  138. self.uploadInfo.uploadAddress,
  139. self.uploadInfo.videoId
  140. );
  141. // })
  142. console.log(
  143. "onUploadStarted:" +
  144. uploadInfo.file.name +
  145. ", endpoint:" +
  146. uploadInfo.endpoint +
  147. ", bucket:" +
  148. uploadInfo.bucket +
  149. ", object:" +
  150. uploadInfo.object
  151. );
  152. // } else {
  153. // // 如果videoId有值,根据videoId刷新上传凭证
  154. // // https://help.aliyun.com/document_detail/55408.html?spm=a2c4g.11186623.6.630.BoYYcY
  155. // let refreshUrl =
  156. // 'https://demo-vod.cn-shanghai.aliyuncs.com/voddemo/RefreshUploadVideo?BusinessType=vodai&TerminalType=pc&DeviceModel=iPhone9,2&UUID=59ECA-4193-4695-94DD-7E1247288&AppVersion=1.0.0&Title=haha1&FileName=xxx.mp4&VideoId=' +
  157. // uploadInfo.videoId
  158. // axios.get(refreshUrl).then(({
  159. // data
  160. // }) => {
  161. // let uploadAuth = data.UploadAuth
  162. // let uploadAddress = data.UploadAddress
  163. // let videoId = data.VideoId
  164. // uploader.setUploadAuthAndAddress(uploadInfo, uploadAuth, uploadAddress, videoId)
  165. // })
  166. // }
  167. },
  168. // 文件上传成功
  169. onUploadSucceed: function(uploadInfo) {
  170. console.log(
  171. "onUploadSucceed: " +
  172. uploadInfo.file.name +
  173. ", endpoint:" +
  174. uploadInfo.endpoint +
  175. ", bucket:" +
  176. uploadInfo.bucket +
  177. ", object:" +
  178. uploadInfo.object
  179. );
  180. self.statusText = "文件上传成功!";
  181. self.goCreate();
  182. },
  183. // 文件上传失败
  184. onUploadFailed: function(uploadInfo, code, message) {
  185. console.log(
  186. "onUploadFailed: file:" +
  187. uploadInfo.file.name +
  188. ",code:" +
  189. code +
  190. ", message:" +
  191. message
  192. );
  193. self.statusText = "文件上传失败!";
  194. },
  195. // 取消文件上传
  196. onUploadCanceled: function(uploadInfo, code, message) {
  197. console.log(
  198. "Canceled file: " +
  199. uploadInfo.file.name +
  200. ", code: " +
  201. code +
  202. ", message:" +
  203. message
  204. );
  205. self.statusText = "文件已暂停上传";
  206. },
  207. // 文件上传进度,单位:字节, 可以在这个函数中拿到上传进度并显示在页面上
  208. onUploadProgress: function(uploadInfo, totalSize, progress) {
  209. console.log(
  210. "onUploadProgress:file:" +
  211. uploadInfo.file.name +
  212. ", fileSize:" +
  213. totalSize +
  214. ", percent:" +
  215. Math.ceil(progress * 100) +
  216. "%"
  217. );
  218. let progressPercent = Math.ceil(progress * 100);
  219. self.btn.title = "已上传" + Math.ceil(progress * 100) + "%";
  220. },
  221. // 上传凭证超时
  222. onUploadTokenExpired: function(uploadInfo) {
  223. // 上传大文件超时, 如果是上传方式一即根据 UploadAuth 上传时
  224. // 需要根据 uploadInfo.videoId 调用刷新视频上传凭证接口(https://help.aliyun.com/document_detail/55408.html)重新获取 UploadAuth
  225. // 然后调用 resumeUploadWithAuth 方法, 这里是测试接口, 所以我直接获取了 UploadAuth
  226. let refreshUrl =
  227. "https://demo-vod.cn-shanghai.aliyuncs.com/voddemo/RefreshUploadVideo?BusinessType=vodai&TerminalType=pc&DeviceModel=iPhone9,2&UUID=59ECA-4193-4695-94DD-7E1247288&AppVersion=1.0.0&Title=haha1&FileName=xxx.mp4&VideoId=" +
  228. uploadInfo.videoId;
  229. axios.get(refreshUrl).then(({ data }) => {
  230. let uploadAuth = data.UploadAuth;
  231. uploader.resumeUploadWithAuth(uploadAuth);
  232. console.log(
  233. "upload expired and resume upload with uploadauth " + uploadAuth
  234. );
  235. });
  236. self.statusText = "文件超时...";
  237. },
  238. // 全部文件上传结束
  239. onUploadEnd: function(uploadInfo) {
  240. console.log("onUploadEnd: uploaded all the files");
  241. self.statusText = "文件上传完毕";
  242. }
  243. });
  244. return uploader;
  245. },
  246. //关闭遮罩
  247. closeVideo() {
  248. this.videoShow = false;
  249. this.$refs.add.value = null;
  250. },
  251. //点击添加按钮
  252. add() {
  253. this.$refs.add.click();
  254. },
  255. //监听用户选择文件
  256. afterRead2(res) {
  257. var that = this;
  258. console.log("---------+++s");
  259. var current = event.target.files[0];
  260. this.file = current;
  261. console.log(current);
  262. if (!current) {
  263. return false;
  264. }
  265. if (current.size >= 1024 * 1024 * 1024) {
  266. Toast.fail("视频文件过大!");
  267. return false;
  268. }
  269. var fileReader = new FileReader();
  270. fileReader.readAsDataURL(current);
  271. var that = this;
  272. fileReader.onload = function(e) {
  273. console.log(e);
  274. that.src = e.currentTarget.result;
  275. that.videoShow = true;
  276. that.filename = current.name;
  277. };
  278. }
  279. }
  280. };
  281. </script>
  282. <style scoped="">
  283. .el-button.is-loading {
  284. position: absolute;
  285. }
  286. .btn {
  287. position: absolute;
  288. right: 7%;
  289. top: 85%;
  290. }
  291. video {
  292. width: 100%;
  293. max-height: 95vh;
  294. margin: auto;
  295. border: 1px solid rgba(200, 200, 200, 0.5);
  296. }
  297. body {
  298. background-color: white;
  299. }
  300. </style>
  301. <style lang='less' scoped>
  302. .wrapper {
  303. position: absolute;
  304. left: 0;
  305. right: 0;
  306. top: 0;
  307. bottom: 0;
  308. margin: auto;
  309. }
  310. .add {
  311. font-size: 50px;
  312. color: gray;
  313. font-weight: 100;
  314. width: 80px;
  315. height: 80px;
  316. line-height: 72px;
  317. text-align: center;
  318. border: 1px dashed rgb(200, 200, 200);
  319. margin-top: 8px;
  320. margin-bottom: 25px;
  321. margin-right: 10px;
  322. }
  323. .box {
  324. margin-top: 40vh;
  325. display: flex;
  326. flex-direction: column;
  327. align-items: center;
  328. }
  329. /* .btn {
  330. width: 2.8rem;
  331. height: 0.8rem;
  332. background: rgba(48, 142, 255, 1);
  333. box-shadow: 0rem 0.04rem 0.12rem 0rem rgba(48, 142, 255, 0.3);
  334. border-radius: 0.04rem;
  335. line-height: 0.8rem;
  336. text-align: center;
  337. font-size: 0.28rem;
  338. font-family: PingFangSC-Medium, PingFang SC;
  339. font-weight: 500;
  340. color: rgba(255, 255, 255, 1);
  341. margin-top: 0.64rem;
  342. }
  343. */
  344. .link > span {
  345. font-size: 0.24rem;
  346. font-family: PingFangSC-Medium, PingFang SC;
  347. font-weight: 500;
  348. color: rgba(48, 142, 255, 1);
  349. }
  350. .link {
  351. font-size: 0.26rem;
  352. font-family: PingFangSC-Regular, PingFang SC;
  353. font-weight: 400;
  354. color: rgba(146, 154, 164, 1);
  355. line-height: 0.36rem;
  356. }
  357. .tip {
  358. width: 82%;
  359. font-size: 0.3rem;
  360. font-family: PingFangSC-Regular, PingFang SC;
  361. font-weight: 400;
  362. color: rgba(44, 52, 62, 0.7);
  363. line-height: 0.51rem;
  364. margin-top: 0.36rem;
  365. margin-bottom: 0.07rem;
  366. }
  367. img {
  368. width: 3.28rem;
  369. height: 2.7rem;
  370. }
  371. </style>