当前位置: 首页 > article >正文

【easy视频 | day03】客户端获取视频分类 + 上传投稿

文章目录

  • 前言
  • 回顾
  • 完成任务
    • 1. 客户端获取视频分类
    • 2. 上传视频(投稿)
      • 2.1 预上传
      • 2.2 视频分片上传
      • 2.3 删除已上传到临时目录的视频
      • 2.4 上传图片
      • 2.5 上传视频
  • 总结

在这里插入图片描述

前言

本项目非原创,我只是个小小白,跟随 b 站脚步,找到老罗的这个项目,视频来源于:
高仿B站(单服务版) springboot项目实战 easylive

本人不分享项目源码,支持项目付费!!!

回顾

昨天完成了视频的分类管理,后台做好了分类工作,现在就可以对客户端发布视频的功能进行处理。

完成任务

1. 客户端获取视频分类

controller 层:
在这里插入图片描述
先前服务端已经将视频的分类保存在了 Redis 中,那么客户端获取的时候,可直接从 Redis 中获取:
在这里插入图片描述
在这里插入图片描述

客户端要获取每个分类的图标和背景图,也需要获取文件的接口,也就是服务端中获取文件的方法 getResource() 是类似的,这里直接将管理端获取的方法 copy 过来(但是,其实并没有那么简单,这里后面还会修改):
在这里插入图片描述
默认的背景图怎么实现的 ?

2. 上传视频(投稿)

2.1 预上传

预上传会向后端请求一个接口,后端返回一个随机字符串,也就是表示这个视频的唯一 Id;后面真正的视频上传请求(也就是每一个切片请求)都会携带这个 Id,这样就知道这个切片上传的是哪个视频的。因为可以有多个视频文件同时上传,所以每个切片要通过这个唯一 Id 找到它自己属于哪个视频。

预上传时,会携带这个文件名,以及分片数目,分片是在客户端完成的:
在这里插入图片描述
预上传,controller 层:
在这里插入图片描述
将视频文件信息存在 Redis 中,并返回生成的视频 Id:
在这里插入图片描述
使用一个文件上传的 Dto 类 UploadingFileDto,主要包括文件上传中需要的相关信息:
在这里插入图片描述
将每上传的文件分片放在临时目录 temp 下,当所有分片完全上传以后,再对 temp 中的分片进行合并,避免在文件上传过程中因为关闭页面或其他原因,使视频没有完全上传,导致正式文件夹中有许多因残余的分片。而 temp 中的文件会在给定的一个时间后进行删除。

2.2 视频分片上传

controller 层:
在这里插入图片描述

  • 每个分片上传时,都会携带先前返回给客户端的视频上传 Id。从 Redis 中获取预上传时存入的上传文件信息,如果不存在,说明在 Redis 中已经过期了(在 Redis 的给定的过期时间内还没有上传完)。

  • SysSettingDto 类是一个与视频相关的系统配置类,包括视频大小、视频数量、评论数量、弹幕数量等:在这里插入图片描述
    在这里插入图片描述
    从 Redis 中获取系统设置信息。

  • 判断分片是否合理,将当前要上传的分片传到 temp 临时目录中。

  • 并在 Redis 中记录上传当前视频的第几块分片,以及总的文件大小:
    在这里插入图片描述

2.3 删除已上传到临时目录的视频

当文件成功上传到服务器后,可以点击选择删除该视频:
在这里插入图片描述

controller 层:
在这里插入图片描述
删掉 Redis 中存储的视频文件,也要删除本地磁盘临时目录 temp 中存放的视频文件。

2.4 上传图片

发布视频,会上传封面:
在这里插入图片描述
点击立即投稿时,会先请求 uploadImage 这个接口来上传封面图片:
在这里插入图片描述

controller 层:
在这里插入图片描述
注意:文件的不为空使用的是 @NotNull,String 类型才可以使用 @NotEmpty。这些都是依赖于 Spring 的 @Validated 注解的,所以必须在类头上加上 @Validated
最后要将图片存储的相对路径返回给客户端,以便于客户端以后获取。

2.5 上传视频

前面做的都是预备工作,接下来才开始将视频上传,存储在数据库中,客户端访问的时候从数据库中获取。

注意新增视频和修改视频用的都是同一个接口,有视频 id 就是修改,没有 id 就是新增。

controller 层:
在这里插入图片描述

  • 上传文件时,可以进行分P投稿,uploadFileList 是选择的所有分P的视频文件的 Json 数据。
    分P” 是什么意思没有发布过 b 站视频的可能并不了解:其实它是指将一个完整的视频分为多个部分(P),并作为一个系列或合集上传到同一个视频页面中。比如,你上传一个教程视频,但这个教程过长,可以通过分P功能把它分成多个小段,每一段称为一个“P”,这样观众在观看时可以更方便地选择具体的部分。
    在这里插入图片描述

通过 videoInfoPostService 调用 saveVideoInfo():
在这里插入图片描述

  • 判断一系列异常情况:(1)上传的分P视频数量超过了系统设置的最大分P数量;(2)videoId 不为空,说明是修改操作,那就要判断这个视频是否存在于数据库中;对于处于转码中和待审核状态的视频,不能修改。
    在这里插入图片描述

如果没有异常的情况,就要看此次操作是新增还是修改,修改包括删除该视频中的分P视频文件,以及对视频分P文件的名称修改,还有对该视频(投搞的视频)的标题,封面,标签,简介的更改
注意:分P文件的文件名是可以修改的:
在这里插入图片描述

在这里插入图片描述

  • 如果这个投稿视频的 videoId 是空的,就说明这是一个新增的视频投稿。

在这里插入图片描述

  • 否则,这个投稿视频应该是进行修改的。
  • 根据 videoId 和 userId 查询数据库中该投稿视频的分P视频文件;将分P视频文件 uploadFileList 根据 uploadId 属性(也就是分P视频的上传Id)放入一个Map中,这样可以通过uploadId快速查找对应的VideoInfoFilePost对象(分P视频文件)。如果存在多个具有相同uploadId的对象,后面的会覆盖前面的。
  • 用 updateFileName 来标记是否有分P视频文件的文件名被修改了。
  • 遍历数据库中的分P视频文件,如果数据库中存在的分P视频文件,在上传的分P视频中不存在,说明此次上传时,将其删除了,所以加入删除列表中。 否则,查看当前遍历的数据库中的分P视频文件的文件名是否与上传的分P视频文件名相同,如果不相同,将 updateFileName 标记为 true(表示有修改)。

在这里插入图片描述

  • 从uploadFileList(本次上传的分P视频文件)中筛选出所有fileId属性为null的对象,并将这些对象收集到新增分P视频文件的列表中。更新投稿视频的最后一次修改时间。
  • 通过 changeVideoInfo() 判断这个投稿视频的标题,封面,标签,简介是否有更改:
    在这里插入图片描述
  • 如果有新增的分P视频文件,那么该投稿视频必须更新状态为转码中;如果没有新增的分P视频,但有修改,则该投稿视频更新状态为审核中。
  • 最后通过 mapper 对这个投稿视频进行修改。

—————————————————————————————————————————————————

以上都是在上传视频过程中,对投稿视频 VideoInfoPost 的操作新增和修改操作。

接下来是对投稿视频中的分P视频文件 VideoInfoFilePost 的操作:
在这里插入图片描述

  • 前面的操作中,已经将要删除的分P视频文件存放在了 deleteFileList 中,通过 mapper 对数据库中的deleteFileList 文件进行删除。
    在这里插入图片描述

  • 同时,也要删除磁盘中的分P视频文件。最好是将要删除的视频加入到消息队列中,通过消息队列慢慢地去删除这个文件,因为这个要删除的视频文件可能很大,而这整个保存视频的操作是在一个事务中的,事务有超时时间,转码操作也一样,也需要放到消息队列中。
    在这里插入图片描述
    不用引入 MQ,Redis 本身也可以做轻量级的消息队列。

在这里插入图片描述

  • 如果是新增的分P视频文件,要设置 FileId,更新状态类型,转码状态:
    在这里插入图片描述
    在这里插入图片描述
  • 通过 mapper 批量删除或修改。

在这里插入图片描述
将新增的分P视频文件也放到消息队列中,让它自己慢慢转码。
在这里插入图片描述

总结

今天的难点是上传投稿中对于上传的视频以及上传视频中的分P视频文件的处理。
要不断看代码才能理解。


http://www.kler.cn/a/570312.html

相关文章:

  • LeetCode 热题 100_最小栈(70_155_中等_C++)(栈)(辅助栈)(栈中的push和emplace对比)
  • 讲一下Spark的shuffle过程
  • 最节省成本的架构方案:无服务器架构
  • Redis存储⑮Redis的应用_分布式锁_Lua脚本/Redlock算法
  • 【FPGA】——verilog实现四位全加器和三八译码器
  • 使用shell脚本读elasticsearch,写msyql
  • 系统架构设计师—计算机基础篇—计算机网络
  • 对比 ThinkPHP 中间件 和 Java AOP
  • 《论云原生架构及其应用》审题技巧 - 系统架构设计师
  • Django 5实用指南(十三)安全性与防护
  • 字符串--子串匹配
  • 【Linux学习笔记】Linux基本指令及其发展史分析
  • 人工智能大模型在物联网应用层上的应用
  • MCP与RAG:增强大型语言模型的两种路径
  • 【星云 Orbit • STM32F4】04.一触即发:GPIO 外部中断
  • 网络问题排查基本命令
  • Android Studio 新版本Gradle通过JitPack发布Maven仓库示例
  • SpringBoot读取properties中文乱码解决方案
  • 【通俗讲解电子电路】——从零开始理解生活中的电路(三)
  • element-push el-date-picker日期时间选择器,禁用可选中的时间 精确到分钟