• 03-视频点播-文件上传及媒资管理


    一、业务需求

    在学成教育中,第三方机构需要将课程视频、作业文档等信息上传,我们采用第三方存储服务来对这些资源做存储,用七牛云存储图片、阿里云做视频点播功能。

    当我们把这些文件上传到第三方服务后,我们需要将第三方服务返回的信息给我们的后端,再由后端将其写入到数据库中。当我们需要访问媒资时首先访问数据库查找对应的媒资信息,再根据fileId向七牛云或阿里云发送获取媒资url的请求,返回给浏览器。
    上面讲了媒资管理“增”和“查”的操作,而“删”并不是删除媒资,也不是删除数据库记录,只是把对应记录的status修改为0(对外不可见),媒资管理并不存在“改”的操作,机构只能修改媒资与章节的绑定关系,并不能对已经上传的媒资进行修改操作

    (一)媒资结构设计

    媒资表(规范字段、媒资信息、公司信息、审核信息、上传者信息)

    1. 规范字段:id、create_date、change_date、status
    2. 媒资基本信息:bucket、filename、file_id、file_type、url
    3. 公司信息:company_id、company_name
    4. 上传者:username
    5. 审核信息:audit_status、audit_mind
      在这里插入图片描述

    (二)主业务流程

    在这里插入图片描述

    二、功能实现

    上传凭证封装类

    @Data
    @ApiModel("视频上传凭证封装类")
    public class VodUploadToken {
    
       /**
        * 请求id
        */
       @ApiModelProperty("请求id")
       private String requestId;
    
       /**
        * 上传视频的唯一标识
        */
       @ApiModelProperty("上传视频的唯一标识")
       private String videoId;
    
       /**
        * 上传URL
        */
       @ApiModelProperty("上传URL")
       private String uploadAddress;
    
       /**
        * 上传凭证
        */
       @ApiModelProperty("上传凭证")
       private String uploadAuth;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    获取、刷新上传token

    获取token

    /**
        * 向阿里云请求上传token
        * @param request (需要包含title、fileName)
        * @return VodUploadToken(videoId、uploadAuth(token)、uploadAddress)
        */
       @RequestMapping("media/vod-token")
       @Override
       public VodUploadToken generatorVodToken(@RequestBody VodUploadRequest request) {
    
          try {
             //1.初始化客户端
             DefaultAcsClient client = AliyunVODUtil.initVodClient(region, accessKey, secretKey);
    
             //2.构建请求并发送,得到响应
             CreateUploadVideoResponse response = AliyunVODUtil.createUploadVideo(client, request.getTitle(), request.getFileName());
    
             //3.解析响应结果
             VodUploadToken uploadToken = new VodUploadToken();
             uploadToken.setUploadAuth(response.getUploadAuth());
             uploadToken.setVideoId(response.getVideoId());
             uploadToken.setUploadAddress(response.getUploadAddress());
             uploadToken.setRequestId(response.getRequestId());
    
             return uploadToken;
          }catch (Exception e){
             System.out.println(e.getMessage());
             ExceptionCast.cast(MediaErrorCode.E_140011);
          }
          return null;
       }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    刷新token

    /**
        * 刷新上传token
        * @param videoId
        * @return
        */
       @GetMapping("media/refresh-vod-token/{videoId}")
       @Override
       public VodUploadToken refreshToken(@PathVariable String videoId) {
          try {
             //1.初始化客户端
             DefaultAcsClient client = AliyunVODUtil.initVodClient(region, accessKey, secretKey);
    
             //2.发送刷新token的请求并得到响应
             RefreshUploadVideoResponse response = AliyunVODUtil.refreshUploadVideo(client, videoId);
    
             //3.解析响应结果
             VodUploadToken uploadToken = new VodUploadToken();
             uploadToken.setUploadAuth(response.getUploadAuth());
             uploadToken.setVideoId(response.getVideoId());
             uploadToken.setUploadAddress(response.getUploadAddress());
             uploadToken.setRequestId(response.getRequestId());
    
             return uploadToken;
          }catch (Exception e){
             ExceptionCast.cast(MediaErrorCode.E_140015);
          }
          return null;
       }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    保存媒资信息

    mediaVO

    @Data
    @ApiModel(value="MediaVO", description="媒体资源VO对象")
    public class MediaVO implements Serializable {
    
        /**
         * 文件名称
         */
        @ApiModelProperty(value = "文件名称")
        @NotNull(message = "文件名不能为空")
        private String filename;
    
        /**
         * 文件类型(文档,音频,视频)
         */
        @ApiModelProperty(value = "文件类型")
        @NotNull(message = "文件类型不能为空")
        private String type;
    
        /**
         * 标签
         */
        @ApiModelProperty(value = "文件标签")
        private String tags;
    
        /**
         * 存储源
         */
        @ApiModelProperty(value = "存储源")
        private String bucket;
    
        /**
         * 文件标识
         */
        @ApiModelProperty(value = "文件唯一标识:七牛云的key,阿里云的videoId")
        @NotNull(message = "文件标识不能为空")
        private String fileId;
    
        /**
         * 媒资文件访问地址
         */
        @ApiModelProperty(value = "文件地址")
        private String url;
    
        @ApiModelProperty(value = "视频长度")
        private String timelength;
    
        /**
         * 备注
         */
        @ApiModelProperty(value = "文件备注")
        private String remark;
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    controller

     @PostMapping("media")
        @Override
        public MediaDTO saveMediaInfo(@RequestBody MediaVO mediaVO) {
            //1.获取公司id
            Long companyId = SecurityUtil.getCompanyId();
    
            //2.将vo转成dto
            MediaDTO dto = MediaConvert.INSTANCE.vo2dto(mediaVO);
            return mediaService.saveMediaInfo(dto,companyId);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    service

    /**
         * 1.检查关键数据
         *      重要字段不能为空
         * 2.校验业务数据
         *       无需校验
         * 3.将dto转为po插入数据库
         *      设置auditStatus为未审核
         * 4.查询数据转为dto返回
         * @param dto
         * @param companyId
         * @return
         */
        @Transactional
        @Override
        public MediaDTO saveMediaInfo(MediaDTO dto, Long companyId) {
            //1.将dto转为po
            Media media = MediaConvert.INSTANCE.dto2po(dto);
    
            //2.为po设置额外信息:companyId和auditStatus
            media.setCompanyId(companyId);
            media.setAuditStatus(AuditEnum.AUDIT_UNPAST_STATUS.getCode());
            boolean save = this.save(media);
            //插入失败则抛出异常
            if(!save){
                ExceptionCast.cast(MediaErrorCode.E_140001);
            }
    
            //3.从数据库中查询新插入的数据
            Media byId = this.getById(media.getId());
    
            MediaDTO mediaDTO = MediaConvert.INSTANCE.po2dto(byId);
    
    
            return mediaDTO;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    预览课程

    预览课程就是通过mediaId和companyName找到对应的媒资信息获得file_id,再用file_id向阿里云发送请求获得url

    controller

    @GetMapping("/media/preview/{mediaId}")
        public String previewMedia(@PathVariable Long mediaId) {
    
            Long companyId = SecurityUtil.getCompanyId();
    
            String vodUrl = mediaService.getVODUrl(mediaId,companyId);
    
            return vodUrl;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    service

     /**
         * 1.关键数据校验
         *      mediaId不为null
         * 2. 业务数据校验
         *      mediaId对应的media不为null
         *      companyId若存在则校验,若不存在则说明是运营方
         * 3. 得到资源key后向阿里云发起请求获得视频url
         *
         * @param mediaId
         * @param companyId
         * @return
         */
        @Override
        public String getVODUrl(Long mediaId, Long companyId) {
    
            //1.关键数据校验
            //        mediaId不为null
            if(ObjectUtils.isEmpty(mediaId)){
                ExceptionCast.cast(MediaErrorCode.E_140005);
            }
    
            //2. 业务数据校验
            //        mediaId对应的media不为null
            Media media = this.getById(mediaId);
            if(media == null){
                ExceptionCast.cast(MediaErrorCode.E_140005);
            }
    
            //companyId若存在则校验,若不存在则说明是运营方
            if (!(ObjectUtils.isEmpty(companyId))) {
                if (!(ObjectUtils.nullSafeEquals(media.getCompanyId(), companyId))) {
                    ExceptionCast.cast(CommonErrorCode.E_100108);
                }
            }
            //3.判断media的url是否存在
            String playUrl = media.getUrl();
            if(ObjectUtils.isEmpty(playUrl)) { //若不存在则向阿里云发送请求,得到url
                playUrl = getPlayUrl(media.getFileId());
            }
            return playUrl;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
  • 相关阅读:
    【PAT甲级 - C++题解】1008 Elevator
    大数据:数据策略之CAP理论和BASE理论
    Java面试题:让依赖注入变得简单,面对@Autowired和@Resource,该如何选择?
    一文了解 Go 标准库 strconv:string 与其他基本数据类型的转换
    【Vue】路由与Node.js下载安装及环境配置教程
    vue3 父子组件间的通信
    基于spring boot 的学生科研项目共享平台毕业设计源码271611
    亲测好用的开发工具【1】 RuoYi-MT
    类和对象(7):初始化列表
    oracle查询相同条件重复值只取第1条
  • 原文地址:https://blog.csdn.net/qq_42861526/article/details/126341958