java 使用 aws s3 sdk 通过分段下载来实现 html 页面 video 的断点播放、拖动进度播放

devtools/2024/9/21 11:28:41/
htmledit_views">

 参考博客:

        1. Java 视频流分段返回

1. html" title=java>java 拉取 html" title=aws>aws s3 视频流返回给浏览器:

    @Overridepublic void playVideo(Long fileLength,String key,HttpServletRequest request,HttpServletResponse response) {OutputStream outputStream = null;S3ObjectInputStream s3ObjectInputStream = null;try {outputStream = response.getOutputStream();// 获取从哪个字节开始读取文件String rangeHeader = request.getHeader("Range");if (rangeHeader == null) {response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Required 'Range' header is missing");return;}long startByte = 0;long endByte = fileLength - 1;if (rangeHeader.startsWith("bytes=")) {String[] rangeParts = rangeHeader.substring(6).split("-");startByte = Long.parseLong(rangeParts[0]);endByte = rangeParts.length > 1 ? startByte : fileLength - 1;}if (startByte > endByte || startByte < 0 || endByte >= fileLength) {response.sendError(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE, "Requested range not satisfiable");return;}// 设置响应头response.setHeader("Content-Type", "video/mp4");response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);response.setHeader("Content-Range", "bytes " + startByte + "-" + endByte + "/" + fileLength);// 从S3获取视频流GetObjectRequest getObjectRequest = new GetObjectRequest(this.fileBucket, key).withRange(startByte, endByte + 1);S3Object s3Object = this.amazonS3.getObject(getObjectRequest);s3ObjectInputStream = s3Object.getObjectContent();// 将视频流响应给客户端byte[] buffer = new byte[1024 * 1024]; // 使用1MB的缓冲区int bytesRead;long totalBytesRead = 0;while ((bytesRead = s3ObjectInputStream.read(buffer)) != -1 && totalBytesRead <= (endByte - startByte + 1)) {outputStream.write(buffer, 0, bytesRead);totalBytesRead += bytesRead;}response.setContentLength((int) (endByte - startByte + 1)); // 设置实际返回的数据长度} catch (Exception e) {// 处理异常log.error( CommonConstans.EXCEPTION_LOG_PREFIX,e );// 处理异常try {response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Internal server error");}catch ( Exception e ){log.error( CommonConstans.EXCEPTION_LOG_PREFIX,e );}}finally {if( outputStream != null ){try {outputStream.close();}catch ( Exception e1 ){log.error( CommonConstans.EXCEPTION_LOG_PREFIX,e1 );}}if( s3ObjectInputStream != null ){try {s3ObjectInputStream.close();}catch ( Exception e1 ){log.error( CommonConstans.EXCEPTION_LOG_PREFIX,e1 );}}}}

2. html" title=java>java读物本地视频文件返回给浏览器:

html" title=java>java">    @Overridepublic void playVideo(HttpServletRequest request, HttpServletResponse response) {RandomAccessFile randomAccessFile = null;OutputStream outputStream = null;try {response.reset();// File file = new File("D:\\素材\\视频\\crazy_max_small.mp4");File file = new File("D:\\视频\\888.mp4");long fileLength = file.length();// 随机读文件randomAccessFile = new RandomAccessFile(file, "r");//获取从那个字节开始读取文件String rangeString = request.getHeader("Range");System.out.println(rangeString);long range=0;if (rangeString!=null) {range = Long.valueOf(rangeString.substring(rangeString.indexOf("=") + 1, rangeString.indexOf("-")));}//获取响应的输出流outputStream = response.getOutputStream();//设置内容类型response.setHeader("Content-Type", "video/mp4");//返回码需要为206,代表只处理了部分请求,响应了部分数据response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);// 移动访问指针到指定位置randomAccessFile.seek(range);// 每次请求只返回1MB的视频流byte[] bytes = new byte[1024 * 1024];int len = randomAccessFile.read(bytes);//设置此次相应返回的数据长度response.setContentLength(len);//设置此次相应返回的数据范围response.setHeader("Content-Range", "bytes "+range+"-"+(fileLength-1)+"/"+fileLength);// 将这1MB的视频流响应给客户端outputStream.write(bytes, 0, len);System.out.println("返回数据区间:【"+range+"-"+(range+len)+"】");}catch ( Exception e ){log.error( CommonConstans.EXCEPTION_LOG_PREFIX,e );// 处理异常try {response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Internal server error");}catch ( Exception e1 ){log.error( CommonConstans.EXCEPTION_LOG_PREFIX,e1 );}}finally {if( outputStream != null){try {outputStream.close();}catch ( Exception e){log.error( CommonConstans.EXCEPTION_LOG_PREFIX,e );}}if( randomAccessFile != null ){try {randomAccessFile.close();}catch ( Exception e ){log.error( CommonConstans.EXCEPTION_LOG_PREFIX,e );}}}


http://www.ppmy.cn/devtools/100784.html

相关文章

深入解析ASP.NET Core 中间件:如何构建高效的请求处理管道

使用ASP.NET Core 中间件实现请求处理管道 前言 ASP.NET Core 是一个跨平台的高性能框架&#xff0c;主要用于构建现代的基于云的、互联网连接的应用程序。在ASP.NET Core 中&#xff0c;Middleware&#xff08;中间件&#xff09;是一个核心概念。中间件是处理HTTP请求和响应…

基于单片机的智能奶茶机(论文+源码+图纸)

1总体架构设计 本课题为基于单片机的智能奶茶机设计&#xff0c;其系统架构上设计如图2.1所示&#xff0c;整个系统包括了DS18B20温度传感器、继电器模块、LCD液晶、蜂鸣器、按键、STC89C52单片机等器件&#xff0c;在功能上用户可以通过按键键控制选择甜度和添加物以及设置温…

Java学习_21_多线程JUC

文章目录 前言多线程并发与并行多线程的实现方式Thread类Runnable接口Callable接口和Future接口 Thread类的相关方法线程对象线程优先级守护线程出让线程/礼让线程插入线程/插队线程 线程的相关问题生命周期安全问题Lock锁死锁等待唤醒机制&#xff08;生产者和消费者&#xff…

React项目-less、antd配置

一、创建Reract项目 1、创建React项目 npx create-react-app react-test 2、运行eject Cesium静态资源需要webpack配置&#xff0c;执行npm run eject可以生成webpack配置&#xff0c;运行前先查看当前git版本是否有提交&#xff0c;如果未提交&#xff0c;需要先本地提交gi…

JAVA-常见八股文(4)-内部类和匿名内部类

【参考文献】 Java 中的内部类与匿名内部类详解_内部类和匿名内部类-CSDN博客 内部类以及匿名内部类详解_匿名内部类的作用-CSDN博客 1.内部类 将一个类 A 定义在另一个类 B 里面&#xff0c;里面的那个类 A 就称为内部类&#xff0c;B 则称为外部类。 特点&#xff1a; 内…

VIM的简单用法

vim三种模式的切换 Set nu&#xff1a;显示行号 Set nonu&#xff1a;不显示行号 Set mousea显示鼠标光标 Set cursorline:显示行线 为什么这些设定默认不能永久存在&#xff1a; 进程结束后&#xff0c;所占的内存空间会被系统回收&#xff0c;资源被释放&#xff0c;这些资源…

5步掌握Python Django+Vue二手房项目,实现房价预测与知识图谱系统

&#x1f34a;作者&#xff1a;计算机毕设匠心工作室 &#x1f34a;简介&#xff1a;毕业后就一直专业从事计算机软件程序开发&#xff0c;至今也有8年工作经验。擅长Java、Python、微信小程序、安卓、大数据、PHP、.NET|C#、Golang等。 擅长&#xff1a;按照需求定制化开发项目…

虚幻5|制作玩家血量,体力(还未编辑,只用于引用)

未编写&#xff0c;仅引用 优化后&#xff1a; 把增加生命&#xff0c;减少生命&#xff0c;也可以用在体力里&#xff0c;更改如下 限制浮点&#xff0c;如果血量或体力按10来扣&#xff0c;如果你的血量降低到5&#xff0c;那么就会以5的数值来扣&#xff0c;而不会扣成-5…