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

java大视频在线预览(支持断点下载)

1.说明

        大视频的在线预览,如果不支持断点下载,将无法在苹果手机上播放,同时不支持进度条拖动.

        之所以这样,是因为视频文件太大了,通过二进制流向浏览器传输时,整个文件尚未传输完成时,会被浏览器强制关闭流,不再接收,等缓存播放到一定程度时,浏览器会再次向后端请求视频文件,同时附带range参数,指定获取数据范围,后端需支持对range参数的处理.

2.代码

    @ResponseBody@GetMapping(value = "/preview")@Operation(summary = "在线预览", description = "文件在浏览器中预览")public void Preview(@RequestParam String fileInfoId, HttpServletRequest request, HttpServletResponse response) throws Exception {//获取存储文件var fileInfo = fileInfoService.Get(fileInfoId);if (fileInfo == null) {response.sendError(HttpServletResponse.SC_NOT_FOUND, "File not found!");return;}//设置页面缓存if (MisFileType.PICTURE.equals(fileInfo.getFile_type()) || MisFileType.TEXT.equals(fileInfo.getFile_type())) {response.setHeader("Cache-Control", "max-age=60");//页面缓存时间60秒}//断点下载ResumeDownload(request, response, fileInfo, "inline");}/*** 支持断点重新下载文件** @param fileInfo    文件* @param disposition 下载方式 inline:内嵌 attachment:附件*/private static void ResumeDownload(HttpServletRequest request, HttpServletResponse response,FileInfoOutput fileInfo, String disposition) throws IOException {//获取存储文件String storageFilePath = FileConfig.Path + File.separator + fileInfo.getFile_path();File storageFile = new File(storageFilePath);if (!StringUtils.hasLength(storageFilePath) || !storageFile.exists()) {//相对路径未找到文件storageFilePath = fileInfo.getFile_absolute_path();//根据绝对路径寻找文件storageFile = new File(storageFilePath);if (!StringUtils.hasLength(storageFilePath) || !storageFile.exists()) {response.sendError(HttpServletResponse.SC_NOT_FOUND, "File not found!");return;}}//推断类型String mimeType = Files.probeContentType(storageFile.toPath());if (!StringUtils.hasLength(mimeType)) {URL url = new URL("file:///" + storageFilePath);mimeType = url.openConnection().getContentType();}//下载开始位置long startByte = 0;//下载结束位置long endByte = storageFile.length() - 1;//获取下载范围String range = request.getHeader("range");if (range != null && range.contains("bytes=") && range.contains("-")) {range = range.substring(range.lastIndexOf("=") + 1).trim();String[] rangeArray = range.split("-");if (rangeArray.length == 1) {//Example: bytes=1024-if (range.endsWith("-")) {startByte = Long.parseLong(rangeArray[0]);} else { //Example: bytes=-1024endByte = Long.parseLong(rangeArray[0]);}}//Example: bytes=2048-4096else if (rangeArray.length == 2) {startByte = Long.parseLong(rangeArray[0]);endByte = Long.parseLong(rangeArray[1]);}}long contentLength = endByte - startByte + 1;//HTTP 响应头设置//断点续传,HTTP 状态码必须为 206,否则不设置,如果非断点续传设置 206 状态码,则浏览器无法下载if (range != null) {log.trace("断点下载range:{},总大小:{},{}({})", range, storageFile.length(), fileInfo.getFile_name(), fileInfo.getId());response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);}if (StringUtils.hasLength(mimeType)) {response.setContentType(mimeType);response.setHeader("Content-Type", mimeType);}response.setHeader("Content-Length", String.valueOf(contentLength));response.setHeader("Accept-Ranges", "bytes");//Content-Range: 下载开始位置-下载结束位置/文件大小response.setHeader("Content-Range", "bytes " + startByte + "-" + endByte + "/" + storageFile.length());//Content-disposition: inline; filename=xxx.xxx 表示浏览器内嵌显示该文件response.setHeader("Content-Disposition", disposition + "; filename=" + URLEncoder.encode(fileInfo.getFile_name(), StandardCharsets.UTF_8));//传输文件流BufferedOutputStream outputStream = null;RandomAccessFile randomAccessFile = null;//已传送数据大小long transmittedLength = 0;try {//以只读模式设置文件指针偏移量randomAccessFile = new RandomAccessFile(storageFile, "r");randomAccessFile.seek(startByte);outputStream = new BufferedOutputStream(response.getOutputStream());byte[] buff = new byte[4096];int len;while (transmittedLength < contentLength && (len = randomAccessFile.read(buff)) != -1) {outputStream.write(buff, 0, len);transmittedLength += len;}outputStream.flush();response.flushBuffer();log.trace("下载完毕:{}-{},下载量:{},总大小:{},{}({})", startByte, endByte, transmittedLength,storageFile.length(), fileInfo.getFile_name(), fileInfo.getId());} catch (IOException e) {if (StringUtils.hasLength(range)) {response.setHeader("Content-Range", "bytes " + startByte + "-" + startByte + transmittedLength + "/" + storageFile.length());log.trace("断点下载完毕:{}-{},下载量:{},总大小:{},{}({})", startByte, endByte, transmittedLength, storageFile.length(),fileInfo.getFile_name(), fileInfo.getId());} else {log.info("下载停止:{}-{},下载量:{},总大小:{},{}({})", startByte, endByte, transmittedLength, storageFile.length(),fileInfo.getFile_name(), fileInfo.getId());}} finally {try {if (randomAccessFile != null) {randomAccessFile.close();}} catch (IOException e) {log.error("下载异常," + fileInfo.getId(), e);}}}

相关文章:

java大视频在线预览(支持断点下载)

1.说明 大视频的在线预览,如果不支持断点下载,将无法在苹果手机上播放,同时不支持进度条拖动. 之所以这样,是因为视频文件太大了,通过二进制流向浏览器传输时,整个文件尚未传输完成时,会被浏览器强制关闭流,不再接收,等缓存播放到一定程度时,浏览器会再次向后端请求视频文件,同…...

OpenCV入门10——特征点检测与匹配

文章目录 特征检测的基本概念Harris角点检测Shi-Tomasi角点检测SIFT关键点检测SIFT计算描述子SURF特征检测OBR特征检测暴力特征匹配FLANN特征匹配实战flann特征匹配图像查找图像拼接基础知识图像拼接实战 特征点检测与匹配是计算机视觉中非常重要的内容。不是所有图像操作都是对…...

教育机构拒绝“数据陷阱”,群硕将英孚新一代教学管理系统搬上桌

为什么小机构年年担心招生不够&#xff0c;英孚却令学生家长趋之若鹜&#xff1f; 区别就在教学管理方式。为了更好地管理分布全球的校区、学生和老师&#xff0c;英孚应用了一套教学管理系统&#xff0c;帮助学校管理学员&#xff0c;帮老师智慧排课&#xff0c;帮助家长记录…...

小辰的智慧树(差分+前缀和)

登录—专业IT笔试面试备考平台_牛客网 1.考虑总长度之和不能超过m&#xff0c;2考虑限制每棵树高度不能低于ci&#xff0c;如果用二分最短输能截到的高度&#xff0c;还要另外去判断&#xff0c;是否每棵树mid都能严格大于ci &#xff0c;这样容易超时&#xff0c;换个角度&…...

Windows如何使用key登录Linux服务器

场景&#xff1a;因为需要回收root管理员权限&#xff0c;禁止root用户远程登录&#xff0c;办公环境只允许普通用户远程登录&#xff0c;且不允许使用密码登录。 一、生成与配置ssh-key 1.使用root管理员权限登录到目标系统。 2.创建一个新的普通用户&#xff0c;和设置密码用…...

k8s无法删除pv,pvc问题

问题&#xff1a; 在k8s里面创建了pv&#xff0c;pvc删除时报错&#xff1a;error: resource(s) were provided, but no name was specified 解决&#xff1a; 正确的删除顺序&#xff1a;1.先删除pod2.再删除pv 3.在删除pvc 删除pv&#xff0c;pvc命令&#xff1a; kubect…...

基于框架的线性回归

线性回归是机器学习中最简单和最常用的回归方法之一。它建立了自变量和因变量之间的线性关系&#xff0c;并通过拟合一条直线或超平面来预测和分析数据。 基于框架的线性回归是构建线性回归模型的一种常见方法&#xff0c;它利用现有的机器学习框架来实现线性回归模型的建立、…...

万宾科技智能井盖传感器使用方式,具有什么效果?

有问题的井盖可能导致人们在行走或驾驶时不经意地踩中或碰到&#xff0c;从而导致摔倒、扭伤或交通事故等安全事故。有问题的井盖可能会破坏井盖和下方污水管道之间的密封性&#xff0c;导致污水泄漏。这不仅会对环境造成污染&#xff0c;还可能对公共卫生和健康构成威胁。 将智…...

13.什么是Spring beans?

什么是Spring beans&#xff1f; Spring 官方文档对 bean 的解释是&#xff1a; In Spring, the objects that form the backbone of your application and that are managed by the Spring IoC container are called beans. A bean is an object that is instantiated, assem…...

算法通关村第十二关|白银|字符串经典基础面试题

1.反转问题 1.1 反转字符串 原题&#xff1a;力扣344. 要求原地修改。 public void reverseString(char[] s) {if (s null || s.length() 0) {return;}int n s.length;for (int left 0, right n - 1; left < right; left, right--) {char temp s[left];s[left] s…...

Spring框架学习 -- 读取和存储Bean对象

目录 &#x1f680;&#x1f680; 回顾 getBean()方法的使用 根据name来获取对象 再谈getBean() (1) 配置扫描路径 (2) 添加注解 ① spring注解简介 ② 对类注解的使用 ③ 注解Bean对象的命名问题 ④ 方法加Bean注解 (3) Bean 注解的重命名 (4) 获取Bean对象 -- …...

APM工具skywalking部署

一 整体架构 整个架构&#xff0c;分成上、下、左、右四部分&#xff1a; 上部分 Agent &#xff1a;负责从应用中&#xff0c;收集链路信息&#xff0c;发送给 SkyWalking OAP 服务器。目前支持 SkyWalking、Zikpin、Jaeger 等提供的 Tracing 数据信息。而我们目前采用的是&…...

MFC打开可执行文件exe

CString exeName, propathdir;//propath _T("D:\\vs2017\\Project\\work\\mySqlselect\\release64\\mySqlselect.exe");//propathdir _T("D:\\vs2017\\Project\\work\\mySqlselect\\elease64\\");//路径太深的时候要指明文件所在路径&#xff0c;奇葩//p…...

css实现原生form表单label必填选项红色*样式,以及js控制必填校验

文章目录 一、css实现原生form表单label必填选项红色*样式&#xff0c;以及js控制必填校验&#xff1f;二、实现方案参考原文 一、css实现原生form表单label必填选项红色*样式&#xff0c;以及js控制必填校验&#xff1f; 二、实现方案 1.css实现原生form表单label必填选项红色…...

10_6 input输入子系统,流程解析

简单分层 应用层 内核层 --------------------------- input handler 数据处理层 driver/input/evdev.c1.和用户空间交互,实现fops2.不知道数据怎么得到的,但是可以把数据上传给用户--------------------------- input core层1.维护上面和下面的两个链表2.为上下两层提供接口--…...

竞赛选题 题目:垃圾邮件(短信)分类 算法实现 机器学习 深度学习 开题

文章目录 1 前言2 垃圾短信/邮件 分类算法 原理2.1 常用的分类器 - 贝叶斯分类器 3 数据集介绍4 数据预处理5 特征提取6 训练分类器7 综合测试结果8 其他模型方法9 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基于机器学习的垃圾邮件分类 该项目…...

Web前端—移动Web第三天(移动Web基础、rem、less、综合案例—极速问诊)

版本说明 当前版本号[20231120]。 版本修改说明20231120初版 本课程的笔记已经更新完毕&#xff0c;各位可以通过点击《黑马程序员2023新版前端Web开发HTML5CSS3移动web视频教程&#xff0c;前端web入门首选》学习笔记总目录查看所有知识点&#xff0c;同时也能免费下载学习…...

MySQL--慢查询(一)

1. 查看慢查询日志是否开启 show variables like slow_query%; show variables like slow_query_log; 参数说明&#xff1a; 1、slow_query_log&#xff1a;这个参数设置为ON&#xff0c;可以捕获执行时间超过一定数值的SQL语句。 2、long_query_time&#xff1a;当SQL语句执行…...

【大神支招】3步,打造一张BI报表

随着BI报表的高效直观、灵活分析的特点越来越被大家所熟知&#xff0c;很多BI零基础的用户可积极尝试制作BI报表&#xff0c;以达到灵活自助分析、高效智能分析的效果。那么BI报表零基础的小白们该怎么做BI报表&#xff0c;才能又快又好地做出来&#xff1f; 大神支招&#xf…...

【Linux】文件操作

欢迎来到Cefler的博客&#x1f601; &#x1f54c;博客主页&#xff1a;那个传说中的man的主页 &#x1f3e0;个人专栏&#xff1a;题目解析 &#x1f30e;推荐文章&#xff1a;题目大解析&#xff08;3&#xff09; 目录 &#x1f449;&#x1f3fb;文件是什么&#xff1f;&am…...

模型评测为什么一做工具调用基准就开始高分低可用:从 Trajectory Scoring 到 Outcome Verification 的工程实战

&#x1f9ea; 离线分数很好看&#xff0c;为什么线上还是频繁把工具调错 很多团队给模型接入搜索、工单、支付或 CRM 工具后&#xff0c;都会先做一套 tool calling benchmark。表面上看&#xff0c;只要模型把工具名和参数拼对&#xff0c;离线分数就会迅速上涨。⚠️ 可一进…...

技术返祖运动:软件测试中的传统智慧回归

在数字技术飞速发展的时代&#xff0c;软件测试从业者面临前所未有的挑战&#xff1a;系统复杂性剧增、数据过载和认知疲劳。技术返祖运动应运而生&#xff0c;它并非简单的历史倒退&#xff0c;而是战略性地回归传统方法&#xff0c;以应对现代测试生态的脆弱性。这场运动的核…...

在Ubuntu 20.04上,除了OpenDaylight,还有哪些SDN控制器值得一试?

在Ubuntu 20.04上探索OpenDaylight之外的SDN控制器生态 当OpenDaylight已经成为你SDN实验环境中的常客时&#xff0c;是否曾好奇过这个开源控制器之外的广阔天地&#xff1f;作为网络工程师或SDN初学者&#xff0c;了解不同控制器的特性就像掌握多种工具&#xff0c;能让你在面…...

TMC2660驱动6线步进电机失败?排查单/双极性接线误区与SPI/STEP/DIR模式选择实战

TMC2660驱动6线步进电机异常排查指南&#xff1a;从单/双极性原理到实战配置 当你的TMC2660驱动板能够完美驱动4线步进电机&#xff0c;却在连接6线电机时遭遇完全无反应的尴尬局面&#xff0c;这种"选择性失灵"往往会让工程师陷入调试泥潭。本文将带你深入电机驱动芯…...

高效保护你的Windows系统:OpenArk反Rootkit工具完整指南

高效保护你的Windows系统&#xff1a;OpenArk反Rootkit工具完整指南 【免费下载链接】OpenArk The Next Generation of Anti-Rookit(ARK) tool for Windows. 项目地址: https://gitcode.com/GitHub_Trending/op/OpenArk 你是否曾担心Windows系统中的隐藏威胁&#xff1f…...

专业干货:低查重AI教材编写工具推荐,高效完成教材创作!

教材编写的困境与AI工具的曙光 教材的初步草稿虽然完成&#xff0c;但接下来的修改和优化过程真的是一场“折磨”&#xff01;通读整篇&#xff0c;寻找逻辑上的漏洞和知识点的错误&#xff0c;需要耗费大量时间&#xff1b;即便是调整一个章节的结构&#xff0c;都会牵扯到后…...

从AWS部署到Node.js路由调试

在现代Web开发中,部署应用程序到云服务已经成为一种常见的实践。特别是对于那些刚接触Node.js、Express和AWS的新手开发者来说,部署过程中的问题往往是学习的良好契机。本文将通过一个实际案例,详细介绍如何在AWS环境中调试Node.js应用程序的路由问题。 背景介绍 最近,我…...

5个步骤,用开源工具彻底解决城通网盘下载难题

5个步骤&#xff0c;用开源工具彻底解决城通网盘下载难题 【免费下载链接】ctfileGet 获取城通网盘一次性直连地址 项目地址: https://gitcode.com/gh_mirrors/ct/ctfileGet 你是否曾在深夜加班时&#xff0c;急需下载一份重要的工作文档&#xff0c;却被城通网盘的限速…...

调试 jar 包时遇到 exec 命令(或进程)一直转圈(挂起/无响应)

在使用IDEA调试项目时&#xff0c;莫名遇到有一个exec命令一直转圈&#xff0c;点击结束调试时&#xff0c;这个命令也一直在转圈&#xff0c;没有停止。以前从来没有遇见过&#xff0c;仔细看启动控制台的启动命令&#xff0c;出现了agentlib、dt_socket、exec-maven-plugin等…...

微信聊天记录永久保存:三步导出完整指南

微信聊天记录永久保存&#xff1a;三步导出完整指南 【免费下载链接】WeChatMsg 提取微信聊天记录&#xff0c;将其导出成HTML、Word、CSV文档永久保存&#xff0c;对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trending/we/WeChatMsg 你是…...