【Easylive】saveVideoInfo 方法详细解析

【Easylive】项目常见问题解答(自用&持续更新中...) 汇总版

saveVideoInfo 方法是一个用于保存视频信息及其关联文件的复杂业务方法,主要处理视频信息的创建、更新以及关联文件的管理。以下是详细解析:

1. 方法概述

java 复制代码
@Override
@Transactional(rollbackFor = Exception.class)
public void saveVideoInfo(VideoInfoPost videoInfoPost, List<VideoInfoFilePost> uploadFileList)

• 事务注解 :@Transactional(rollbackFor = Exception.class) 表示该方法在一个事务中执行,遇到任何异常都会回滚

• 参数 :

• videoInfoPost:视频主信息

• uploadFileList:视频关联的文件列表

2. 分P数校验

java 复制代码
if (uploadFileList.size() > redisComponent.getSysSettingDto().getVideoPCount()) {
    throw new BusinessException(ResponseCodeEnum.CODE_600);
}

• 功能 :检查上传的视频分P数是否超过系统设置的最大限制

• 实现 :

• 从Redis获取系统设置

• 比较上传文件列表大小与系统允许的最大分P数

• 超过则抛出业务异常

3. 视频ID存在性校验

java 复制代码
if(!StringTools.isEmpty(videoInfoPost.getVideoId())){
    VideoInfoPost videoInfoPostDb = this.videoInfoPostMapper.selectByVideoId(videoInfoPost.getVideoId());
    if (videoInfoPostDb == null) {
        throw new BusinessException(ResponseCodeEnum.CODE_600);
    }
    if (ArrayUtils.contains(new Integer[]{VideoStatusEnum.STATUS0.getStatus(), VideoStatusEnum.STATUS2.getStatus()}, videoInfoPostDb.getStatus())) {
        throw new BusinessException(ResponseCodeEnum.CODE_600);
    }
}

• 功能 :当videoId不为空时,检查视频是否存在及状态是否允许修改

• 逻辑:

复制代码
1. 查询数据库中是否存在该videoId对应的记录
2. 不存在则抛出异常
3. 检查视频状态是否为"审核中"或"待审核",是则不允许修改

4. 初始化变量

java 复制代码
Date curDate = new Date();
String videoId = videoInfoPost.getVideoId();
List<VideoInfoFilePost> deleteFileList = new ArrayList<>();
List<VideoInfoFilePost> addFileList = uploadFileList;

• 变量说明 :

• curDate:当前时间,用于设置创建/更新时间

• videoId:视频ID

• deleteFileList:待删除的文件列表

• addFileList:待添加的文件列表(初始化为全部上传文件)

5. 新增视频逻辑

java 复制代码
if (StringTools.isEmpty(videoId)) {
    videoId = StringTools.getRandomString(Constants.LENGTH_10);
    videoInfoPost.setVideoId(videoId);
    videoInfoPost.setCreateTime(curDate);
    videoInfoPost.setLastUpdateTime(curDate);
    videoInfoPost.setStatus(VideoStatusEnum.STATUS0.getStatus());
    this.videoInfoPostMapper.insert(videoInfoPost);
}

• 条件 :videoId为空表示新增视频

• 操作:

复制代码
1. 生成随机videoId
2. 设置创建时间、更新时间
3. 设置初始状态为"待审核"
4. 插入数据库

6. 更新视频逻辑

java 复制代码
else {
    // 查询数据库中的文件列表
    VideoInfoFilePostQuery fileQuery = new VideoInfoFilePostQuery();
    fileQuery.setVideoId(videoId);
    fileQuery.setUserId(videoInfoPost.getUserId());
    List<VideoInfoFilePost> dbInfoFileList = this.videoInfoFilePostMapper.selectList(fileQuery);
    
    // 将上传文件列表转为Map方便查询
    Map<String, VideoInfoFilePost> uploadFileMap = uploadFileList.stream()
        .collect(Collectors.toMap(item -> item.getUploadId(), Function.identity(), (data1, data2) -> data2));

    Boolean updateFileName = false;
    // 比较数据库文件和上传文件
    for(VideoInfoFilePost fileInfo : dbInfoFileList){
        VideoInfoFilePost updateFile = uploadFileMap.get(fileInfo.getUploadId());
        if (updateFile == null) {
            deleteFileList.add(fileInfo);
        } else if (!updateFile.getFileName().equals(fileInfo.getFileName())) {
            updateFileName = true;
        }
    }
    
    // 筛选新增文件
    addFileList = uploadFileList.stream()
        .filter(item->item.getFileId()==null)
        .collect(Collectors.toList());
    
    // 更新视频信息
    videoInfoPost.setLastUpdateTime(curDate);
    Boolean changeVideoInfo = this.changeVideoInfo(videoInfoPost);
    
    // 设置视频状态
    if (addFileList != null && !addFileList.isEmpty()) {
        videoInfoPost.setStatus(VideoStatusEnum.STATUS0.getStatus());
    } else if (changeVideoInfo || updateFileName) {
        videoInfoPost.setStatus(VideoStatusEnum.STATUS2.getStatus());
    }
    
    this.videoInfoPostMapper.updateByVideoId(videoInfoPost, videoInfoPost.getVideoId());
}

• 核心逻辑:

复制代码
1. 查询数据库中该视频已有的文件列表
2. 比较数据库文件和上传文件:
   ◦ 数据库有但上传没有 → 加入删除列表
   ◦ 文件名被修改 → 标记为需要更新
3. 筛选出新增文件(fileId为null)
4. 根据情况设置视频状态:
   ◦ 有新增文件 → 待审核
   ◦ 视频信息或文件名被修改 → 待审核
5. 更新视频主信息

7. 处理待删除文件

java 复制代码
if (!deleteFileList.isEmpty()) {
    List<String> delFileList = deleteFileList.stream()
        .map(item->item.getFileId())
        .collect(Collectors.toList());
    this.videoInfoFilePostMapper.deleteBatchByFileId(delFileList, videoInfoPost.getUserId());
    
    List<String> delFilePathList = deleteFileList.stream()
        .map(item->item.getFilePath())
        .collect(Collectors.toList());
    redisComponent.addFile2DelQueue(videoId, delFilePathList);
}

• 操作:

复制代码
1. 从数据库批量删除文件记录
2. 将要删除的文件路径加入Redis删除队列(异步删除实际文件)

8. 处理文件索引和新增文件

java 复制代码
Integer index = 1;
for (VideoInfoFilePost videoInfoFile : uploadFileList) {
    videoInfoFile.setFileIndex(index++);
    videoInfoFile.setVideoId(videoId);
    videoInfoFile.setUserId(videoInfoPost.getUserId());
    if (videoInfoFile.getFileId() == null) {
        videoInfoFile.setFileId(StringTools.getRandomString(Constants.LENGTH_20));
        videoInfoFile.setUpdateType(VideoFileUpdateTypeEnum.UPDATE.getStatus());
        videoInfoFile.setTransferResult(VideoFileTransferResultEnum.TRANSFER.getStatus());
    }
}
this.videoInfoFilePostMapper.insertOrUpdateBatch(uploadFileList);

• 操作:

复制代码
1. 为每个文件设置索引(排序)
2. 设置视频ID和用户ID
3. 对新文件(fileId为null):
   ◦ 生成随机fileId
   ◦ 设置更新类型为"更新"
   ◦ 设置传输结果为"待传输"
4. 批量插入或更新文件记录

9. 处理新增文件传输

java 复制代码
if (addFileList != null && !addFileList.isEmpty()) {
    for (VideoInfoFilePost file : addFileList) {
        file.setUserId(videoInfoPost.getUserId());
        file.setVideoId(videoId);
    }
    redisComponent.addFile2TransferQueue(addFileList);
}

• 功能:将新增文件加入传输队列(可能是转码、转存等异步处理)

方法总结

saveVideoInfo 方法是一个复杂的视频信息保存方法,主要功能包括:

  1. 参数校验:检查分P数限制、视频状态是否允许修改
  2. 新增视频:生成ID、设置初始状态、插入数据库
  3. 更新视频 :
    • 比较新旧文件列表,识别新增、删除和修改的文件
    • 根据修改情况设置视频状态
    • 更新视频主信息
  4. 文件处理 :
    • 删除不再需要的文件记录和实际文件
    • 为新增文件生成ID并设置属性
    • 批量保存文件信息
    • 将新增文件加入处理队列

该方法通过精细的状态管理和文件比较,实现了视频信息的完整保存流程,同时考虑了事务一致性和异步处理的需求。

相关推荐
驭渊的小故事2 小时前
MyBatis XML 开发实战:从配置到 CRUD 全解析
xml·java·mybatis
哦虎!7 小时前
【JavaEE】网络初识
java
for_ever_love__8 小时前
MySQL ORDER BY 排序优化:从 Using filesort 到索引有序扫描(含双路 / 单路排序原理)
java·mysql·优化·存储·by·order·filesort
我是人✓8 小时前
Java文件上传三方式对比:从传统到SpringBoot
java·开发语言
欣栀♡9 小时前
JVM 频繁 Full GC 先看日志括号里的 cause,jstat 的 FGC 在 JDK 8 上会骗人
java·jvm
IT研究室9 小时前
最新计算机毕业设计选题推荐-基于spring boot的葡萄酒文化宣传网站-网站-文档指导-Java-springboot
java·spring boot·课程设计
慧都小项9 小时前
MyEclipse 中创建和测试 JAX-RS REST 接口:从项目配置到 REST Explorer
java·restful·myeclipse·jax-rs
Wang's Blog9 小时前
Java 项目实战: 交友项目 - 入门案例:编写 Dubbo 服务提供者
java·dubbo·交友
秋饼10 小时前
Spring AI 2.0 结构化输出企业级实战:从 BeanOutputConverter 源码到生产级解析容错
java·ai·技术分享·后端开发
摇滚侠10 小时前
《计算机是如何工作的:人人都能懂的计算机软硬件工作原理》第 9 章 机器码与汇编语言 阅读笔记 9
java·开发语言·笔记