视频断点上传
什么是断点续传
通常视频文件都比较大,所以对于媒资系统上传文件的需求要满足大文件的上传要求。http协议本身对上传文件大小没有限制,但是客户的网络环境质量、电脑硬件环境等参差不齐,如果一个大文件快上传完了网断了没有上传完成,需要客户重新上传,用户体验非常差,所以对于大文件上传的要求最基本的是断点续传。
什么是断点续传:
引用百度百科:断点续传指的是在下载或上传时,将下载或上传任务(一个文件或一个压缩包)人为的划分为几个部分,每一个部分采用一个线程进行上传或下载,如果碰到网络故障,可以从已经上传或下载的部分开始继续上传下载未完成的部分,而没有必要从头开始上传下载,断点续传可以提高节省操作时间,提高用户体验性。
断点续传流程如下图:

流程如下:
1、前端上传前先把文件分成块
2、一块一块的上传,上传中断后重新上传,已上传的分块则不用再上传
3、各分块上传完成最后在服务端合并文件
文件分块
文件分块的流程如下:
1、获取源文件长度
2、根据设定的分块文件的大小计算出块数
3、从源文件读数据依次向每一个块文件写数据。
/*** 文件分块上传测试*/@Testpublic void testChunk(){//获取源文件File sourceFile = new File("B:\\workspace\\test\\you.ncm");//源文件字节大小long length = sourceFile.length();//分块文件目录String chunkPath="B:\\workspace\\test\\chunk\\";File chunkFolder = new File(chunkPath);//检查目录是否存在if (!chunkFolder.exists()) {//不存在就创建chunkFolder.mkdirs();}//分块大小long chunkSize = 1024*1024*1;//分块数量long chunkNum = (long) Math.ceil(length * 1.0 / chunkSize);//缓冲区大小byte[] b = new byte[1024];//使用RandomAccessFile访问文件try {RandomAccessFile read = new RandomAccessFile(sourceFile, "r");for (int i = 0; i < chunkNum; i++) {//创建分块文件File file = new File(chunkPath + i);//检查文件是否存在,如果存在就删除文件if(file.exists()){file.delete();}//创建一个新文件boolean newFile = file.createNewFile();if (newFile){//向分块文件中写数据RandomAccessFile write = new RandomAccessFile(file,"rw");int len = -1;while ((len = read.read(b)) != -1) {write.write(b, 0, len);//如果分块文件的大小大于等于分块大小就跳过本次循环if (file.length() >= chunkSize) {break;}}write.close();System.out.println("完成分块"+i);}}read.close();} catch (Exception e) {e.printStackTrace();}}
RandomAccessFile 是 Java 中的一个类,它允许对文件的任意位置进行读写操作。与其他的输入/输出流(如 InputStream 和 OutputStream)不同,RandomAccessFile 并不属于它们的类系,而是直接继承自 Object 类。它提供了类似于文件系统中的随机访问功能,因此得名“随机访问文件”。
以下是 RandomAccessFile 的一些主要特点和功能:
- 随机访问:
RandomAccessFile允许你直接跳到文件的任意位置来读写数据。这是通过使用seek(long pos)方法实现的,它可以将文件的指针移动到指定的位置。 - 读写功能:
RandomAccessFile既可以从文件中读取数据,也可以向文件中写入数据。它提供了类似于InputStream的read()方法和类似于OutputStream的write()方法来执行这些操作。 - 文件指针操作:除了
seek(long pos)方法外,RandomAccessFile还提供了getFilePointer()方法来返回文件记录指针的当前位置。 - 访问模式:在创建
RandomAccessFile对象时,你需要指定一个访问模式,它决定了文件是以只读方式打开还是以读写方式打开。常见的访问模式有 "r"(只读)和 "rw"(读写)。 - 文件操作模式:在 JDK 1.6 及更高版本中,
RandomAccessFile还支持 "rws" 和 "rwd" 模式。在 "rws" 模式下,每次写入操作都会确保数据被写入到磁盘中;而在 "rwd" 模式下,只有在对文件执行了某些特定的更新操作(如关闭文件或调用flush()方法)后,数据才会被写入到磁盘中。 - 内存映射文件:虽然
RandomAccessFile提供了强大的文件访问功能,但在某些情况下,使用 JDK 1.4 引入的“内存映射文件”可能会更高效。内存映射文件允许你将文件的一部分或全部映射到内存中,从而可以像访问内存一样快速地访问文件。
文件合并
文件合并流程:
1、找到要合并的文件并按文件合并的先后进行排序。
2、创建合并文件
3、依次从合并的文件中读取数据向合并文件写入数
文件合并的测试代码 :
//测试文件合并方法@Testpublic void testMerge(){try {//获取源文件File sourceFile = new File("B:\\workspace\\test\\you.ncm");//分块文件目录String chunkPath="B:\\workspace\\test\\chunk\\";//合并后的文件File mergeFile = new File("B:\\workspace\\test\\you1.ncm");if (mergeFile.exists()) {mergeFile.delete();}//创建新的合并文件mergeFile.createNewFile();RandomAccessFile write = new RandomAccessFile(mergeFile,"rw");//指针指向文件顶端write.seek(0);//缓冲区byte[] b = new byte[1024];//获取分块文件数组File file = new File(chunkPath);File[] files = file.listFiles();// 转成集合,便于排序List<File> fileList = Arrays.asList(files);//使用工具类和自定义比较类进行排序Collections.sort(fileList, new Comparator<File>() {@Overridepublic int compare(File o1, File o2) {Integer o1Name = Integer.parseInt(o1.getName());Integer o2Name=Integer.parseInt(o2.getName());return o1Name-o2Name;}});//合并文件for (File file1 : fileList) {RandomAccessFile read = new RandomAccessFile(file1,"r");int len = -1;while ((len = read.read(b)) != -1) {write.write(b, 0, len);}read.close();}write.close();//校验文件FileInputStream fileInputStream = new FileInputStream(sourceFile);FileInputStream mergeFileStream = new FileInputStream(mergeFile);//取出原始文件的md5String originalMd5 = DigestUtils.md5Hex(fileInputStream);//取出合并文件的md5进行比较String mergeFileMd5 = DigestUtils.md5Hex(mergeFileStream);if (originalMd5.equals(mergeFileMd5)) {System.out.println("合并文件成功");} else {System.out.println("合并文件失败");}} catch (Exception e) {e.printStackTrace();}}
视频上传流程
1、前端对文件进行分块。
2、前端上传分块文件前请求媒资服务检查文件是否存在,如果已经存在则不再上传。
3、如果分块文件不存在则前端开始上传
4、前端请求媒资服务上传分块。
5、媒资服务将分块上传至MinIO。
6、前端将分块上传完毕请求媒资服务合并分块。
7、媒资服务判断分块上传完成则请求MinIO合并文件。
8、合并完成校验合并后的文件是否完整,如果不完整则删除文件。
测试将分块文件上传至minio
//将分块文件上传至minio@Testpublic void uploadChunk(){String chunkFolderPath = "B:\\workspace\\test\\chunk\\";File chunkFolder = new File(chunkFolderPath);//分块文件File[] files = chunkFolder.listFiles();//将分块文件上传至miniofor (int i = 0; i < files.length; i++) {try {UploadObjectArgs uploadObjectArgs = UploadObjectArgs.builder().bucket("testbucket")//桶名.object("chunk/" + i)//存储路径+文件名.filename(files[i].getAbsolutePath()).build();minioClient.uploadObject(uploadObjectArgs);System.out.println("上传分块成功"+i);} catch (Exception e) {e.printStackTrace();}}}
测试通过minio的合并文件
//合并文件,要求分块文件最小5M@Testpublic void test_merge() throws Exception {List<ComposeSource> sources = new ArrayList<>();for (int i = 0; i <=7; i++) {ComposeSource composeSource = ComposeSource.builder()//指定分块文件信息.bucket("testbucket").object("chunk/" + (Integer.toString(i)))//目标文件信息.build();sources.add(composeSource);}ComposeObjectArgs composeObjectArgs = ComposeObjectArgs.builder().bucket("testbucket").object("merge01.npm")//目标文件.sources(sources)//源文件.build();//合并文件minioClient.composeObject(composeObjectArgs);}
测试minio清除分块文件
//清除分块文件@Testpublic void test_removeObjects(){//合并分块完成将分块文件清除List<DeleteObject> deleteObjects = Stream.iterate(0, i -> ++i).limit(2)//循环几次.map(i -> new DeleteObject("chunk/".concat(Integer.toString(i)))).collect(Collectors.toList());RemoveObjectsArgs removeObjectsArgs = RemoveObjectsArgs.builder().bucket("testbucket").objects(deleteObjects).build();Iterable<Result<DeleteError>> results = minioClient.removeObjects(removeObjectsArgs);results.forEach(r->{DeleteError deleteError = null;try {deleteError = r.get();} catch (Exception e) {e.printStackTrace();}});}
相关文章:
视频断点上传
什么是断点续传 通常视频文件都比较大,所以对于媒资系统上传文件的需求要满足大文件的上传要求。http协议本身对上传文件大小没有限制,但是客户的网络环境质量、电脑硬件环境等参差不齐,如果一个大文件快上传完了网断了没有上传完成…...
清华团队开发首个AI医院小镇模拟系统;阿里云发布通义千问 2.5:超越GPT-4能力;Mistral AI估值飙升至60亿美元
🦉 AI新闻 🚀 清华团队开发首个AI医院小镇模拟系统 摘要:来自清华的研究团队最近开发出了一种创新的模拟系统,名为"Agent Hospital",该系统能够完全模拟医患看病的全流程,其中包括分诊、挂号、…...
React Suspense与Concurrent Mode:探索异步渲染的新范式
React的Suspense和Concurrent Mode是两个强大的特性,它们共同改变了React应用处理异步数据加载和UI渲染的方式。下面我将通过一个简化的代码示例来展示如何使用这两个特性。 Concurrent Mode 和 Suspense 的基本用法 首先,确保你使用的是支持这些特性的…...
算法训练营day37
动态规划 1.斐波那契数 1.使用数组存储子问题结果 class Solution {public int fib(int N) {if (N 0) return 0;int[] dp new int[N 1];// base casedp[0] 0; dp[1] 1;// 状态转移for (int i 2; i < N; i) {dp[i] dp[i - 1] dp[i - 2];}return dp[N];} }2.使用变…...
基础ArkTS组件:帧动画,内置动画组件,跑马灯组件(HarmonyOS学习第三课【3.6】)
帧动画 帧动画也叫序列帧动画,其原理就是在时间轴的每帧上逐帧绘制不同的内容,使其连续播放而成动画。ArkUI开发框架提供了 ImageAnimator 组件实现帧动画能力,本节笔者介绍一下 ImageAnimator 组件的简单使用。 官方文献 说明 该组件从A…...
vant NavBar 导航栏详解
vant 是一个基于 Vue 的移动端 UI 组件库,而 NavBar 是其中的一个导航栏组件。下面是对 vant 的 NavBar 导航栏组件的详细解释: 1. 引入 NavBar 首先,你需要在你的 Vue 组件中引入 NavBar 组件: import { NavBar } from vant; …...
Python自动化办公实战案例:文件整理与邮件发送
目录 一、引言 二、案例背景 三、实战案例 (一)文件自动整理 (二)邮件自动发送 四、结语 一、引言 随着办公自动化的兴起,Python作为一门强大的编程语言,逐渐被应用于日常办公中。从文件整理到邮件…...
2024中国(重庆)无人机展览会8月在重庆举办
2024中国(重庆)无人机展览会8月在重庆举办 邀请函 主办单位: 中国航空学会 重庆市南岸区人民政府 招商执行单位: 重庆港华展览有限公司 报名:【交易会I 59交易会2351交易会9466】 展会背景: 为更好的培养航空航天产业和无人…...
自动驾驶技术与传感器数据处理
目录 自动驾驶总体架构 感知系统 决策系统 定位系统 计算平台 仿真平台 自动驾驶公开数据集 激光点云 点云表征方式 1) 原始点云 2) 三维点云体素化 3)深度图 4)鸟瞰图 点云检测障碍物的步骤 PCL点云库 车载毫米波雷达 车载相机 设备标定 自动驾驶…...
高效测评系统方案助力沃尔玛、亚马逊卖家提升产品销量
无论在哪个电商平台,测评确实是最有效的推广方式。测之前一定要选好产品,因为对于大部分卖家而言,不可能你店铺里所有的都是爆款,所以选择的是需要有潜力成为爆款的产品。测评是指通过搭建安全的环境模拟真实的买家购物行为&#…...
B/S模式的web通信(高并发服务器)
这里写目录标题 目标实现的目标 服务器代码(采用epoll实现服务器)整体框架main函数init_listen_fd函数(负责对lfd初始化的那一系列操作)epoll_run函数do_accept函数do_read函数内容补充:http中的getline函数 详解do_re…...
C语言每日一题—约瑟夫问题
13个人围成一圈,从第1个人开始顺序报号1、2、3,凡报到3的人退出圈子。找出最后留在圈子里的人原来的序号。要求用结构体编程实现。***输出提示:"\n出圈成员及顺序:" ***输出格式:"%3d" ***输出提示…...
语言:C#
一、VSCode生成exe 二、...
[力扣题解]45. 跳跃游戏 II
题目:45. 跳跃游戏 II 思路 贪心法; 只需记录2个变量,当前点能达到的最远距离,和上一步能到达的最远距离; (真有意思,代码随想录给出的是curDistance,nextDistance2个,…...
pywinauto操作windows应用(未完成)
pywinauto 脚本制作 一 、获取窗口句柄 首先获取句柄,其次扫描组件,然后对按钮和文本进行操作 安装依赖 pip install pywin32 -i https://pypi.doubanio.com/simple扫描全部的句柄 import win32gui# GetDesktopWindow 获得代表整个屏幕的一个窗口&a…...
(超详细讲解)实现将idea的java程序打包成exe (新版,可以在没有java的电脑下运行,即可以发给好朋友一起玩)
目录 实现打包到exe大概步骤 工具准备 1.将java程序文件打包成jar文件 2.准备好jre文件 3.使用exe4j软件打包好 4.最终打包 实现打包到exe大概步骤 1.打包需要满足的条件:将java文件转成jar文件的工具exe4j、 以及需要满足jdk1.8以上(因安装exe4…...
学习软考----数据库系统工程师29
数据操作 SELECT基本结构 简单查询 连接查询 子查询 聚集函数 分组查询 字符串操作 集合操作 外连接 INSERT INTO语句 DELETE语句 UPDATE语句...
STL中的优先级队列
目录 1.引言 2.简介 3.基本操作 4.实现原理 5.自定义优先级比较 6.相关题目 7.能特点 8.总结 1.引言 在C标准库中,优先级队列是一种非常有用的数据结构,它允许我们根据元素的优先级来对其进行排序和访问。这种数据结构在多种应用场景中都发挥着重…...
浅谈Acrel-2000ES储能能量管理系统的设计与应用-安科瑞 蒋静
0 前言 为进一步提升河南省分布式光伏发电发展水平,促进行业健康可持续发展,河南省发布关于促进分布式光伏发电健康可持续发展的通知。对于储能行业,可以用到安科瑞Acrel-2000ES储能能量管理系统。 储能柜EMS能量管理系统 1、产品名称 储…...
会员卡积分小程序系统源码商业运营版 行业一站式解决方案附带源代码以及搭建安装部署教程
系统概述 会员卡积分小程序系统源码商业运营版是一套完整的会员卡积分系统解决方案,包含前端小程序、后端管理系统以及数据库设计。该系统支持多种会员卡类型、积分规则设定、积分兑换、优惠券发放等功能,满足企业对于会员积分管理的各种需求。同时&…...
Spring Boot 实现流式响应(兼容 2.7.x)
在实际开发中,我们可能会遇到一些流式数据处理的场景,比如接收来自上游接口的 Server-Sent Events(SSE) 或 流式 JSON 内容,并将其原样中转给前端页面或客户端。这种情况下,传统的 RestTemplate 缓存机制会…...
【2025年】解决Burpsuite抓不到https包的问题
环境:windows11 burpsuite:2025.5 在抓取https网站时,burpsuite抓取不到https数据包,只显示: 解决该问题只需如下三个步骤: 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...
IT供电系统绝缘监测及故障定位解决方案
随着新能源的快速发展,光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域,IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选,但在长期运行中,例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...
MySQL账号权限管理指南:安全创建账户与精细授权技巧
在MySQL数据库管理中,合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号? 最小权限原则…...
SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)
上一章用到了V2 的概念,其实 Fiori当中还有 V4,咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务),代理中间件(ui5-middleware-simpleproxy)-CSDN博客…...
Android第十三次面试总结(四大 组件基础)
Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成,用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机: onCreate() 调用时机:Activity 首次创建时调用。…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...
RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)
RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发,后来由Pivotal Software Inc.(现为VMware子公司)接管。RabbitMQ 是一个开源的消息代理和队列服务器,用 Erlang 语言编写。广泛应用于各种分布…...
PostgreSQL——环境搭建
一、Linux # 安装 PostgreSQL 15 仓库 sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-$(rpm -E %{rhel})-x86_64/pgdg-redhat-repo-latest.noarch.rpm# 安装之前先确认是否已经存在PostgreSQL rpm -qa | grep postgres# 如果存在࿰…...
人工智能 - 在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型
在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型。这些平台各有侧重,适用场景差异显著。下面我将从核心功能定位、典型应用场景、真实体验痛点、选型决策关键点进行拆解,并提供具体场景下的推荐方案。 一、核心功能定位速览 平台核心定位技术栈亮…...
