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

文章目录

  • 前言
  • 回顾
  • 完成任务
    • [1. 客户端获取视频分类](#1. 客户端获取视频分类)
    • [2. 上传视频(投稿)](#2. 上传视频(投稿))
      • [2.1 预上传](#2.1 预上传)
      • [2.2 视频分片上传](#2.2 视频分片上传)
      • [2.3 删除已上传到临时目录的视频](#2.3 删除已上传到临时目录的视频)
      • [2.4 上传图片](#2.4 上传图片)
      • [2.5 上传视频](#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视频文件的处理。

要不断看代码才能理解。

相关推荐
码熔burning2 小时前
(十 九)趣学设计模式 之 中介者模式!
java·设计模式·中介者模式
_TokaiTeio2 小时前
微服务100道面试题
java·微服务
eqwaak02 小时前
基于Spring Cloud Alibaba的电商系统微服务化实战:从零到生产级部署
java·分布式·微服务·云原生·架构
m0_672656542 小时前
【Rabbitmq篇】高级特性----TTL,死信队列,延迟队列
java·rabbitmq·java-rabbitmq
胡图蛋.2 小时前
Spring 中哪些情况下,不能解决循环依赖问题?
java·后端·spring
24k小善2 小时前
Flink Oceanbase Connector详解
java·大数据·flink
ChinaRainbowSea3 小时前
8. Nginx 配合 + Keepalived 搭建高可用集群
java·运维·服务器·后端·nginx
猫头鹰~3 小时前
Ubuntu20.04安装Redis
java·数据库·redis
吃瓜市民3 小时前
146. LRU 缓存
算法·缓存·lru
小志开发3 小时前
Java 多态:代码中的通用设计模式
java·开发语言