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

devtools/2025/3/4 21:06:14/

文章目录

  • 前言
  • 回顾
  • 完成任务
    • 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.ppmy.cn/devtools/164556.html

相关文章

JavaWeb后端基础(4)

这一篇就开始是做一个项目了,在项目里学习,我主要记录在学习过程中遇到的问题,以及一些知识点 Restful风格 一种软件架构风格 在REST风格的URL中,通过四种请求方式,来操作数据的增删改查。 GET : 查询 …

江协科技/江科大-51单片机入门教程——P[3-1] 独立按键控制LED亮灭

本文围绕51单片机开发中的独立按键控制技术展开,系统讲解其硬件结构、电平检测原理与C51编程实现方法。文章从开发板独立按键的物理构造与电路连接入手,剖析按键按下与松开时的电平变化规律,并结合单片机I/O口寄存器操作原理,阐释…

【Elasticsearch】Data Streams

Elasticsearch 的Data Streams是一种用于高效管理和存储时间序列数据(如日志、事件、指标等)的机制。它通过将数据分散到多个后端索引中,同时提供一个统一的接口,使得用户可以像操作单个索引一样操作整个数据流。以下是关于 Data …

第七章:项目实战 - 第三节 - Tailwind CSS 电商网站开发

本节将介绍如何使用 Tailwind CSS 开发一个现代化的电商网站,包括商品展示、购物车、结算流程等核心功能的实现。 商品列表 商品卡片组件 // components/ProductCard.tsx interface ProductCardProps {product: {id: string;title: string;price: number;image: …

在笔记本电脑上用DeepSeek搭建个人知识库

最近DeepSeek爆火,试用DeepSeek的企业和个人越来越多。最常见的应用场景就是知识库和知识问答。所以本人也试用了一下,在笔记本电脑上部署DeepSeek并使用开源工具搭建一套知识库,实现完全在本地环境下使用本地文档搭建个人知识库。操作过程共…

不用写代码,批量下载今日头条文章导出excel和pdf

前几天有人问我怎么批量抓取今日头条某个号的所有文章数据,需要文章链接,标题和时间,但是不会写代码,于是我写了个简单的教程 这里以渤海小吏为例 首先用edge浏览器安装web-scraper浏览器扩展 然后打开浏览器控制台,找…

springboot相关随记-2025

GraalVM Native Support:GraalVM 是一个高性能的多语言运行时,该插件提供对 GraalVM 原生镜像构建的支持 。可以将 Java 应用程序打包成原生可执行文件,脱离 JVM 运行,带来更快的启动时间和更低的内存消耗,适合对性能敏…

神经网络中的Adagrad

Adagrad(Adaptive Gradient)是一种自适应学习率的优化算法,专门设计用于在训练过程中自动调整每个参数的学习率。这种方法对于处理稀疏数据特别有效,并且非常适合那些需要频繁更新但很少使用的参数的学习任务。 ### Adagrad的核心…