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

SpringBoot 实现视频分段播放(通过进度条来加载视频)

需求:现在我本地电脑中有一个文件夹,文件夹中都是视频,需要实现视频播放的功能。

问题:如果通过类似 SpringBoot static 文件夹的方式来实现,客户端要下载好完整的视频之后才可以播放,并且服务端也会占用大量宽带。所以这里考虑采取视频分段的方式进行下载,客户端播放视频时,可以通过进度条调节视频进度。

实现方法:在 SpringBoot 中支持自定义资源请求处理器,通过自定义的资源处理器来实现。

依赖:主要就是 SpringBoot 的相关依赖:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId>
</dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>

编写一个自定义资源请求处理器,需要继承 ResourceHttpRequestHandler 重写 getResource() 方法。该自定义处理器还需要加上 @Component 注解。

在案例中 getResource() 方法中,需要拿到对应的视频地址,通过 Controller 层的代码通过 request.setAttribute("video-uri", videoUri) 设置 video-uri 的 value,value 可以是视频的本地路径,也可以是视频的唯一标识,需要按照自己的业务来传值。

import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.resource.ResourceHttpRequestHandler;import javax.servlet.http.HttpServletRequest;/*** @author 17279*/
@Component
public class VideoResourceHttpRequestHandler extends ResourceHttpRequestHandler {// 只需要重写 getResource 方法@Overrideprotected Resource getResource(HttpServletRequest request) {// 这里的 videoUri 是在 Controller 中通过 request.setAttribute("video-uri", videoUri) 进来的值String videoUri = (String) request.getAttribute("video-uri"); // D:\Downloads\test.mp4// 可以通过 videoUri 传递的值根据我们的业务查找对应的文件return new FileSystemResource(videoUri);}
}

编写 Controller 层代码:

这里通过 request.setAttribute("video-uri", videoUri) 添加 video-uri 的 value,自定义处理中通过这个 value 找到向前端返回的视频。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.resource.ResourceHttpRequestHandler;import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;/*** @author 17279*/@RestController
@RequestMapping("video")
public class VideoController {@Autowiredprivate ResourceHttpRequestHandler resourceHttpRequestHandler;/*** @param fileName fileName 前端传递过来的视频文件名名称*/@GetMapping(value = "/{fileName}")public void video(@PathVariable("fileName") String fileName, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {// 视频文件根目录【换成实际的视频根目录】final String videoBasePath = "D:/Downloads/";// 视频根目录 + 文件名称,找到对应的文件String videoUri = videoBasePath + fileName;Path videoPath = Paths.get(videoUri);if (Files.exists(videoPath)) {// 如果找到视频,那么返回视频信息String contentType = Files.probeContentType(videoPath);if (contentType != null && !"".equals(contentType)) {response.setContentType(contentType);}// video-path 主要是将视频的地址传递给自定义的资源处理器处使用request.setAttribute("video-uri", videoUri);resourceHttpRequestHandler.handleRequest(request, response);} else {// 如果文件不存在,那么跳到 404 页面response.setStatus(HttpServletResponse.SC_NOT_FOUND);response.setCharacterEncoding(StandardCharsets.UTF_8.toString());}}
}

访问地址:http://localhost/video/test.mp4

访问效果:这里设置的视频跟目录是 D:/Downloads/,前端传递的 fileName 为 test.mp4,所以实际返回前端的文件为 D:/Downloads/test.mp4

在这里插入图片描述

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • [面试爱问] https 的s是什么意思,有什么作用?
  • VUE之旅—day3
  • ExcelVBA运用Excel的【条件格式】(三)
  • 【文档智能】LACE:帮你自动生成文档布局的方法浅尝
  • c++初阶学习----入门(上)
  • Cesium版本升级webgl问题,glsl代码关键字修改
  • 通过高德地图 JS API实现单击鼠标进行标注
  • 基于 sftp 的 NAS (局域网文件存储服务器)
  • Linux文件编程(打开/创建写入读取移动光标)
  • 语义言语流畅性的功能连接和有效连接
  • YOLOv5改进系列(32)——替换主干网络之PKINet(CVPR2024 | 面向遥感旋转框主干,有效捕获不同尺度上的密集纹理特征)
  • `DynamicDataSourceContextHolder` 是一个在Java应用程序中用于动态切换数据源的实用类
  • 蝙蝠优化算法(Bat Algorithm,BA)及其Python和MATLAB实现
  • springboot集成tika解析word,pdf,xls文件文本内容
  • 科普文:分布式系统的架构设计模式
  • [数据结构]链表的实现在PHP中
  • 【mysql】环境安装、服务启动、密码设置
  • cookie和session
  • CoolViewPager:即刻刷新,自定义边缘效果颜色,双向自动循环,内置垂直切换效果,想要的都在这里...
  • Java比较器对数组,集合排序
  • Python学习之路16-使用API
  • Synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比...
  • 从零到一:用Phaser.js写意地开发小游戏(Chapter 3 - 加载游戏资源)
  • 多线程事务回滚
  • 基于OpenResty的Lua Web框架lor0.0.2预览版发布
  • 码农张的Bug人生 - 初来乍到
  • 每个JavaScript开发人员应阅读的书【1】 - JavaScript: The Good Parts
  • 如何设计一个微型分布式架构?
  • 使用SAX解析XML
  • 一天一个设计模式之JS实现——适配器模式
  • 因为阿里,他们成了“杭漂”
  • 与 ConTeXt MkIV 官方文档的接驳
  • MPAndroidChart 教程:Y轴 YAxis
  • postgresql行列转换函数
  • raise 与 raise ... from 的区别
  • ​html.parser --- 简单的 HTML 和 XHTML 解析器​
  • ​数据链路层——流量控制可靠传输机制 ​
  • # 手柄编程_北通阿修罗3动手评:一款兼具功能、操控性的电竞手柄
  • #【QT 5 调试软件后,发布相关:软件生成exe文件 + 文件打包】
  • #Linux(Source Insight安装及工程建立)
  • (11)MSP430F5529 定时器B
  • (3)选择元素——(17)练习(Exercises)
  • (32位汇编 五)mov/add/sub/and/or/xor/not
  • (C语言)求出1,2,5三个数不同个数组合为100的组合个数
  • (html转换)StringEscapeUtils类的转义与反转义方法
  • (超简单)构建高可用网络应用:使用Nginx进行负载均衡与健康检查
  • (二)丶RabbitMQ的六大核心
  • (附源码)springboot家庭装修管理系统 毕业设计 613205
  • (十六)视图变换 正交投影 透视投影
  • (算法)Travel Information Center
  • (贪心 + 双指针) LeetCode 455. 分发饼干
  • (心得)获取一个数二进制序列中所有的偶数位和奇数位, 分别输出二进制序列。
  • (转)C#开发微信门户及应用(1)--开始使用微信接口
  • .NET 读取 JSON格式的数据
  • .Net的C#语言取月份数值对应的MonthName值