• el-upload 上传视频时,动态截取视频第一帧画面作为封面展示


            最近项目有上传视频的需求,但 Element 的 el-upload上传视频后,回显异常,不会显示视频内容(如下图)

            通过在网上查找截取视频第一帧的方法,自己稍加修改,得以正常显示封面,如下图:

            本方法采用前端动态获取第一帧画面,后端不保存当前视频第一帧信息。这样做,好处是:修改及删除视频时,不用做额外的关联封面处理,减少交互以及省去服务器保存封面资源,不好的地方就是:如果视频过大,获取第一帧封面的时间会比较长,本人亲测,40几M的视频,差不多2-3秒左右加载封面出来,但针对此问题,可以先默认加载系统预设默认封面,待视频处理完后,再加载第一帧画面。

    1. JS 中获取视频第一帧方法

    1. /**
    2. * 获取视频第一帧作为回显封面
    3. * @param file 至少应包含url信息,即 {url: ""}
    4. */
    5. getVideoCover(file) {
    6. let _self = this;
    7. _self.$set(file, 'videoUrl', _self.$utils.deepClone(file.url)); //备份视频源路径,用于后续预览展示
    8. const video = document.createElement("video") // 也可以自己创建video
    9. video.src = file.url // url地址 url跟 视频流是一样的
    10. file.url = videoDefCover; //设置默认封面,videoDefCover 为预制的默认封面,不需要可去除或替换成自己的
    11. let canvas = document.createElement('canvas') // 获取 canvas 对象
    12. const ctx = canvas.getContext('2d'); // 绘制2d
    13. video.crossOrigin = 'anonymous' // 解决跨域问题,也就是提示污染资源无法转换视频
    14. video.currentTime = 1 // 第一帧
    15. video.oncanplay = () => {
    16. console.log(video.clientWidth, video.clientHeight);
    17. canvas.width = video.clientWidth ? video.clientWidth : 320; // 获取视频宽度
    18. canvas.height = video.clientHeight ? video.clientHeight : 320; //获取视频高度
    19. // 利用canvas对象方法绘图
    20. ctx.drawImage(video, 0, 0, canvas.width,canvas.height)
    21. // 转换成base64形式
    22. let _videoFirstimgsrc = canvas.toDataURL ("image/png"); // 截取后的视频封面
    23. _self.$set(file, 'url', _videoFirstimgsrc); //重置文件的url为当前截取的封面,用于 el-upload展示
    24. video.remove();
    25. canvas.remove();
    26. }
    27. },

    2. el-upload 设置

    2.1 上传成功后回显调用

    1. handleUploadSuccess(response, file, fileList) { //为 el-upload on-success 方法实现
    2. let _self = this;
    3. _self.fileList = fileList;
    4. if (response.code != 0) {
    5. _self.$message({
    6. message: '附件上传失败',
    7. type: 'error'
    8. })
    9. _self.fileList.splice(_self.fileList.indexOf(file, 1))
    10. } else {
    11. let _fileName = file.name;
    12. if (_self.$utils.getFileIsVideo(_fileName)) { //getFileIsVideo 为我本地自定义判断是否是视频方法,可自己修改
    13. //视频附件,获取第一帧画面作为 封面展示
    14. _self.getVideoCover(file);
    15. }
    16. }
    17. },

    2.2 页面编辑、数据回显

    1. /**
    2. * 查看详情时附件回显
    3. **/
    4. setFileList(_fileList) {
    5. let _self = this;
    6. if (_self.$utils.isNotEmpty(_fileList)) {
    7. for (let obj of _fileList) {
    8. //视频附件,获取第一帧画面作为 封面展示
    9. let _fileName = obj.name;
    10. if (_self.$utils.getFileIsVideo(_fileName)) { //getFileIsVideo为我自定义的判断是否是视频的方法,可以自己修改
    11. //视频附件,获取第一帧画面作为 封面展示
    12. _self.getVideoCover(obj);
    13. }
    14. }
    15. }
    16. _self.fileList = _fileList; //fileList 为 Element file-list 参数值
    17. },

     至此处理完成。

            预览时,在预览弹窗中判断是否是视频,如果是视频的话,直接取文件的 videoUrl 参数值进行加载展示。

  • 相关阅读:
    无胁科技-TVD每日漏洞情报-2022-8-16
    以科技传递温度,vivo亮相数字中国建设峰会
    Python中的@lru_cache装饰器
    ROS-Ubuntu 版本相关
    Netty面试题(二)
    全解析异步编程的几种方法
    【C/C++】函数作为参数
    若依框架解读(微服务版)——2.模块间的调用逻辑(ruoyi-api模块)(OpenFeign)
    ConcurrentHashMap:并发的hashmap
    HBuilderX修改manifest.json设置,解决跨域问题(CORS、Cross-Origin)
  • 原文地址:https://blog.csdn.net/sinat_35626559/article/details/127734155