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

视频断点上传

什么是断点续传

通常视频文件都比较大,所以对于媒资系统上传文件的需求要满足大文件的上传要求。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 的一些主要特点和功能:

  1. 随机访问RandomAccessFile 允许你直接跳到文件的任意位置来读写数据。这是通过使用 seek(long pos) 方法实现的,它可以将文件的指针移动到指定的位置。
  2. 读写功能RandomAccessFile 既可以从文件中读取数据,也可以向文件中写入数据。它提供了类似于 InputStream 的 read() 方法和类似于 OutputStream 的 write() 方法来执行这些操作。
  3. 文件指针操作:除了 seek(long pos) 方法外,RandomAccessFile 还提供了 getFilePointer() 方法来返回文件记录指针的当前位置。
  4. 访问模式:在创建 RandomAccessFile 对象时,你需要指定一个访问模式,它决定了文件是以只读方式打开还是以读写方式打开。常见的访问模式有 "r"(只读)和 "rw"(读写)。
  5. 文件操作模式:在 JDK 1.6 及更高版本中,RandomAccessFile 还支持 "rws" 和 "rwd" 模式。在 "rws" 模式下,每次写入操作都会确保数据被写入到磁盘中;而在 "rwd" 模式下,只有在对文件执行了某些特定的更新操作(如关闭文件或调用 flush() 方法)后,数据才会被写入到磁盘中。
  6. 内存映射文件:虽然 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();}});}

相关文章:

视频断点上传

什么是断点续传 通常视频文件都比较大&#xff0c;所以对于媒资系统上传文件的需求要满足大文件的上传要求。http协议本身对上传文件大小没有限制&#xff0c;但是客户的网络环境质量、电脑硬件环境等参差不齐&#xff0c;如果一个大文件快上传完了网断了没有上传完成&#xf…...

清华团队开发首个AI医院小镇模拟系统;阿里云发布通义千问 2.5:超越GPT-4能力;Mistral AI估值飙升至60亿美元

&#x1f989; AI新闻 &#x1f680; 清华团队开发首个AI医院小镇模拟系统 摘要&#xff1a;来自清华的研究团队最近开发出了一种创新的模拟系统&#xff0c;名为"Agent Hospital"&#xff0c;该系统能够完全模拟医患看病的全流程&#xff0c;其中包括分诊、挂号、…...

React Suspense与Concurrent Mode:探索异步渲染的新范式

React的Suspense和Concurrent Mode是两个强大的特性&#xff0c;它们共同改变了React应用处理异步数据加载和UI渲染的方式。下面我将通过一个简化的代码示例来展示如何使用这两个特性。 Concurrent Mode 和 Suspense 的基本用法 首先&#xff0c;确保你使用的是支持这些特性的…...

算法训练营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】)

帧动画 帧动画也叫序列帧动画&#xff0c;其原理就是在时间轴的每帧上逐帧绘制不同的内容&#xff0c;使其连续播放而成动画。ArkUI开发框架提供了 ImageAnimator 组件实现帧动画能力&#xff0c;本节笔者介绍一下 ImageAnimator 组件的简单使用。 官方文献 说明 该组件从A…...

vant NavBar 导航栏详解

vant 是一个基于 Vue 的移动端 UI 组件库&#xff0c;而 NavBar 是其中的一个导航栏组件。下面是对 vant 的 NavBar 导航栏组件的详细解释&#xff1a; 1. 引入 NavBar 首先&#xff0c;你需要在你的 Vue 组件中引入 NavBar 组件&#xff1a; import { NavBar } from vant; …...

Python自动化办公实战案例:文件整理与邮件发送

目录 一、引言 二、案例背景 三、实战案例 &#xff08;一&#xff09;文件自动整理 &#xff08;二&#xff09;邮件自动发送 四、结语 一、引言 随着办公自动化的兴起&#xff0c;Python作为一门强大的编程语言&#xff0c;逐渐被应用于日常办公中。从文件整理到邮件…...

2024中国(重庆)无人机展览会8月在重庆举办

2024中国(重庆)无人机展览会8月在重庆举办 邀请函 主办单位&#xff1a; 中国航空学会 重庆市南岸区人民政府 招商执行单位&#xff1a; 重庆港华展览有限公司 报名&#xff1a;【交易会I 59交易会2351交易会9466】 展会背景&#xff1a; 为更好的培养航空航天产业和无人…...

自动驾驶技术与传感器数据处理

目录 自动驾驶总体架构 感知系统 决策系统 定位系统 ​计算平台​ 仿真平台​ 自动驾驶公开数据集 激光点云 点云表征方式 1) 原始点云 2) 三维点云体素化 3)深度图 4)鸟瞰图 点云检测障碍物的步骤 PCL点云库 车载毫米波雷达 车载相机 设备标定 自动驾驶…...

高效测评系统方案助力沃尔玛、亚马逊卖家提升产品销量

无论在哪个电商平台&#xff0c;测评确实是最有效的推广方式。测之前一定要选好产品&#xff0c;因为对于大部分卖家而言&#xff0c;不可能你店铺里所有的都是爆款&#xff0c;所以选择的是需要有潜力成为爆款的产品。测评是指通过搭建安全的环境模拟真实的买家购物行为&#…...

B/S模式的web通信(高并发服务器)

这里写目录标题 目标实现的目标 服务器代码&#xff08;采用epoll实现服务器&#xff09;整体框架main函数init_listen_fd函数&#xff08;负责对lfd初始化的那一系列操作&#xff09;epoll_run函数do_accept函数do_read函数内容补充&#xff1a;http中的getline函数 详解do_re…...

C语言每日一题—约瑟夫问题

13个人围成一圈&#xff0c;从第1个人开始顺序报号1、2、3&#xff0c;凡报到3的人退出圈子。找出最后留在圈子里的人原来的序号。要求用结构体编程实现。***输出提示&#xff1a;"\n出圈成员及顺序&#xff1a;" ***输出格式&#xff1a;"%3d" ***输出提示…...

语言:C#

一、VSCode生成exe 二、...

[力扣题解]45. 跳跃游戏 II

题目&#xff1a;45. 跳跃游戏 II 思路 贪心法&#xff1b; 只需记录2个变量&#xff0c;当前点能达到的最远距离&#xff0c;和上一步能到达的最远距离&#xff1b; &#xff08;真有意思&#xff0c;代码随想录给出的是curDistance&#xff0c;nextDistance2个&#xff0c;…...

pywinauto操作windows应用(未完成)

pywinauto 脚本制作 一 、获取窗口句柄 首先获取句柄&#xff0c;其次扫描组件&#xff0c;然后对按钮和文本进行操作 安装依赖 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.打包需要满足的条件&#xff1a;将java文件转成jar文件的工具exe4j、 以及需要满足jdk1.8以上&#xff08;因安装exe4…...

学习软考----数据库系统工程师29

数据操作 SELECT基本结构 简单查询 连接查询 子查询 聚集函数 分组查询 字符串操作 集合操作 外连接 INSERT INTO语句 DELETE语句 UPDATE语句...

STL中的优先级队列

目录 1.引言 2.简介 3.基本操作 4.实现原理 5.自定义优先级比较 6.相关题目 7.能特点 8.总结 1.引言 在C标准库中&#xff0c;优先级队列是一种非常有用的数据结构&#xff0c;它允许我们根据元素的优先级来对其进行排序和访问。这种数据结构在多种应用场景中都发挥着重…...

浅谈Acrel-2000ES储能能量管理系统的设计与应用-安科瑞 蒋静

0 前言 为进一步提升河南省分布式光伏发电发展水平&#xff0c;促进行业健康可持续发展&#xff0c;河南省发布关于促进分布式光伏发电健康可持续发展的通知。对于储能行业&#xff0c;可以用到安科瑞Acrel-2000ES储能能量管理系统。 储能柜EMS能量管理系统 1、产品名称 储…...

会员卡积分小程序系统源码商业运营版 行业一站式解决方案附带源代码以及搭建安装部署教程

系统概述 会员卡积分小程序系统源码商业运营版是一套完整的会员卡积分系统解决方案&#xff0c;包含前端小程序、后端管理系统以及数据库设计。该系统支持多种会员卡类型、积分规则设定、积分兑换、优惠券发放等功能&#xff0c;满足企业对于会员积分管理的各种需求。同时&…...

uniapp 百度地图 拖动获取经纬度级搜索连用

import loadBMap from /utils/loadBMap.js// 百度聚合具体代码 // 拖动 initMapc() {let that thisloadBMap(百度key).then(() > {map new BMap.Map(mapContainer)const centerPoint new BMap.Point(this.longitude, this.latitude)map.centerAndZoom(centerPoint, this.…...

Yarn的安装和使用详细教程(Mac/Window)

目录 Yarn是什么&#xff1f; Mac安装Yarn 使用Homebrew安装Yarn 使用npm安装Yarn Windows安装Yarn 使用npm安装Yarn Yarn使用 常用命令&#xff1a; 特殊命令&#xff1a; Yarn是什么&#xff1f; Yarn是一个流行的包管理工具&#xff0c;用于管理JavaScript项目的依…...

高考志愿系统-学生管理模块分析

1.获取学生信息&#xff1a; 接口&#xff1a;http://localhost:81/dev-api/college_entrance/student/list?pageNum1&pageSize10 请求方式get 默认传参pageNum和pageSize&#xff0c;表示当前页&#xff0c;每页展示数量 首先通过startPage()方法获取分页参数当前页&…...

【问题实操】银河高级服务器操作系统实例分享,开机之后反复重启

1.服务器环境以及配置 物理机/虚拟机/云/容器 物理机 外网/私有网络/无网络 私有网络 处理器&#xff1a; PHYTIUM FT2000PLUS 2200 MHz 内存&#xff1a; 128 GiB 整机类型/架构&#xff1a; HIKVISION DS-V BIOS版本&#xff1a; HK 601FBE02HK 网卡&#xff1…...

攻防世界-web-unseping

题目 知识点 PHP代码审计PHP序列化和反序列化PHP中魔术方法命令执行绕过方式 解读源码 <?php highlight_file(__FILE__);class ease{private $method;private $args;function __construct($method, $args) {$this->method $method;$this->args $args;}function …...

网络网络层之(4)IPv4协议

网络网络层之(1)IPv4协议 Author: Once Day Date: 2024年4月4日 一位热衷于Linux学习和开发的菜鸟&#xff0c;试图谱写一场冒险之旅&#xff0c;也许终点只是一场白日梦… 漫漫长路&#xff0c;有人对你微笑过嘛… 全系列文档可参考专栏&#xff1a;通信网络技术_Once-Day的…...

16-LINUX--线程安全

一。线程安全 线程安全即就是在多线程运行的时候&#xff0c;不论线程的调度顺序怎样&#xff0c;最终的结果都是 一样的、正确的。那么就说这些线程是安全的。 要保证线程安全需要做到&#xff1a; 1&#xff09; 对线程同步&#xff0c;保证同一时刻只有一个线程访问临界资…...

Flask SQLAlchemy 技术指南

文章目录 什么是 Flask SQLAlchemy&#xff1f;安装 Flask SQLAlchemy创建 Flask 应用和数据库模型添加和查询数据运行 Flask 应用总结**数据库迁移&#xff08;Database Migrations&#xff09;****复杂查询****关系模型****事务处理****性能优化****安全性****扩展功能** Fla…...

js通过时间对JSON中的数据进行排序

需求 现在需要通过每一个数据段的date字段对数组的整体数据进行排序&#xff01; 元数据如下&#xff1a; var data [{"filename": "123","date": "2024-05-10 19:53:57","stand": "GB-14","filter":…...

leetcode206-Reverse Linked List

题目 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[5,4,3,2,1] 分析 用一个指针记录当前位置&#xff0c;另外一个指针记录当前位置的前一个位置&#xff0c…...