上传图片视频

分布式文件系统MinIo

MinIO提供多个语言版本SDK的支持,下边找到java版本的文档:

地址:https://docs.min.io/docs/java-client-quickstart-guide.html

MinIO测试(上传、删除、下载)

public class MinioTest {MinioClient minioClient =MinioClient.builder().endpoint("http://192.168.101.65:9000")//对象存储服务的URL//Access key就像用户ID,可以唯一标识你的账户。Secret key是你账户的密码。.credentials("minioadmin", "minioadmin").build();@Testpublic void test_upload() throws Exception {//通过扩展名得到媒体资源类型 mimeType//根据扩展名取出mimeTypeContentInfo extensionMatch = ContentInfoUtil.findExtensionMatch(".mp4");String mimeType = MediaType.APPLICATION_OCTET_STREAM_VALUE;//通用mimeType,字节流if(extensionMatch!=null){mimeType = extensionMatch.getMimeType();}//上传文件的参数信息UploadObjectArgs uploadObjectArgs = UploadObjectArgs.builder().bucket("testbucket")//桶.filename("D:\\develop\\upload\\1.mp4") //指定本地文件路径.object("test/01/1.mp4")//对象名 放在子目录下.contentType(mimeType)//设置媒体文件类型.build();//上传文件minioClient.uploadObject(uploadObjectArgs);}//删除文件@Testpublic void test_delete() throws Exception {//RemoveObjectArgsRemoveObjectArgs removeObjectArgs = RemoveObjectArgs.builder().bucket("testbucket").object("1.mp4").build();//删除文件minioClient.removeObject(removeObjectArgs);}//查询文件 从minio中下载@Testpublic void test_getFile() throws Exception {GetObjectArgs getObjectArgs = GetObjectArgs.builder().bucket("testbucket").object("test/01/1.mp4").build();//查询远程服务获取到一个流对象FilterInputStream inputStream = minioClient.getObject(getObjectArgs);//指定输出流FileOutputStream outputStream = new FileOutputStream(new File("D:\\develop\\upload\\1a.mp4"));IOUtils.copy(inputStream,outputStream);//校验文件的完整性对文件的内容进行md5FileInputStream fileInputStream1 = new FileInputStream(new File("D:\\develop\\upload\\1.mp4"));String source_md5 = DigestUtils.md5Hex(fileInputStream1);FileInputStream fileInputStream = new FileInputStream(new File("D:\\develop\\upload\\1a.mp4"));String local_md5 = DigestUtils.md5Hex(fileInputStream);if(source_md5.equals(local_md5)){System.out.println("下载成功");}}
}

上传视频-断点续传

流程如下:

1、前端上传前先把文件分成块

2、一块一块的上传,上传中断后重新上传,已上传的分块则不用再上传

3、各分块上传完成最后在服务端合并文件

视频分块合并测试

public class BigFileTest {//分块测试@Testpublic void testChunk() throws IOException {//源文件File sourceFile = new File("D:\\develop\\upload\\1.项目背景.mp4");//分块文件存储路径String chunkFilePath = "D:\\develop\\upload\\chunk\\";//分块文件大小int chunkSize = 1024 * 1024 * 5;//分块文件个数int chunkNum = (int) Math.ceil(sourceFile.length() * 1.0 / chunkSize);//使用流从源文件读数据,向分块文件中写数据RandomAccessFile raf_r = new RandomAccessFile(sourceFile, "r");//缓存区byte[] bytes = new byte[1024];for (int i = 0; i < chunkNum; i++) {File chunkFile = new File(chunkFilePath + i);//分块文件写入流RandomAccessFile raf_rw = new RandomAccessFile(chunkFile, "rw");int len = -1;while ((len=raf_r.read(bytes))!=-1){raf_rw.write(bytes,0,len);if(chunkFile.length()>=chunkSize){break;}}raf_rw.close();}raf_r.close();}//将分块进行合并@Testpublic void testMerge() throws IOException {//块文件目录File chunkFolder = new File("D:\\develop\\upload\\chunk");//源文件File sourceFile = new File("D:\\develop\\upload\\1.项目背景.mp4");//合并后的文件File mergeFile = new File("D:\\develop\\upload\\1.项目背景_2.mp4");//取出所有分块文件File[] files = chunkFolder.listFiles();//将数组转成listList<File> filesList = Arrays.asList(files);//对分块文件排序Collections.sort(filesList, new Comparator<File>() {@Overridepublic int compare(File o1, File o2) {return Integer.parseInt(o1.getName())-Integer.parseInt(o2.getName());}});//向合并文件写的流RandomAccessFile raf_rw = new RandomAccessFile(mergeFile, "rw");//缓存区byte[] bytes = new byte[1024];//遍历分块文件,向合并 的文件写for (File file : filesList) {//读分块的流RandomAccessFile raf_r = new RandomAccessFile(file, "r");int len = -1;while ((len=raf_r.read(bytes))!=-1){raf_rw.write(bytes,0,len);}raf_r.close();}raf_rw.close();//合并文件完成后对合并的文件md5校验FileInputStream fileInputStream_merge = new FileInputStream(mergeFile);FileInputStream fileInputStream_source = new FileInputStream(sourceFile);String md5_merge = DigestUtils.md5Hex(fileInputStream_merge);String md5_source = DigestUtils.md5Hex(fileInputStream_source);if(md5_merge.equals(md5_source)){System.out.println("文件合并成功");}}
}

视频上传流程

1、前端对文件进行分块。

2、前端上传分块文件前请求媒资服务检查文件是否存在,如果已经存在则不再上传。

3、如果分块文件不存在则前端开始上传

4、前端请求媒资服务上传分块。

5、媒资服务将分块上传至MinIO。

6、前端将分块上传完毕请求媒资服务合并分块。

7、媒资服务判断分块上传完成则请求MinIO合并文件。

8、合并完成校验合并后的文件是否完整,如果不完整则删除文件。

MinIo分块上传合并视频测试

//将分块文件上传到minio@Testpublic void uploadChunk() throws IOException, ServerException, InsufficientDataException, ErrorResponseException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {for (int i = 0; i < 6; i++) {//上传文件的参数信息UploadObjectArgs uploadObjectArgs = UploadObjectArgs.builder().bucket("testbucket")//桶.filename("D:\\develop\\upload\\chunk\\"+i) //指定本地文件路径.object("chunk/"+i)//对象名 放在子目录下.build();//上传文件minioClient.uploadObject(uploadObjectArgs);System.out.println("上传分块"+i+"成功");}}//调用minio接口合并分块@Testpublic void testMerge() throws Exception {//        List<ComposeSource> sources = new ArrayList<>();
//        for (int i = 0; i < 30; i++) {
//            //指定分块文件的信息
//            ComposeSource composeSource = ComposeSource.builder().bucket("testbucket").object("chunk/" + i).build();
//            sources.add(composeSource);
//        }List<ComposeSource> sources = Stream.iterate(0, i -> ++i).limit(6).map(i -> ComposeSource.builder().bucket("testbucket").object("chunk/" + i).build()).collect(Collectors.toList());//指定合并后的objectName等信息ComposeObjectArgs composeObjectArgs = ComposeObjectArgs.builder().bucket("testbucket").object("merge01.mp4").sources(sources)//指定源文件.build();//合并文件,//报错size 1048576 must be greater than 5242880,minio默认的分块文件大小为5MminioClient.composeObject(composeObjectArgs);}//清除分块文件@Testpublic void test_removeObjects(){//合并分块完成将分块文件清除List<DeleteObject> deleteObjects = Stream.iterate(0, i -> ++i).limit(6).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();}});}

 视频转码(avi转成mp4)

使用FFmpeg对视频进行编码

        //ffmpeg的路径String ffmpeg_path = "D:\\soft\\ffmpeg\\ffmpeg.exe";//ffmpeg的安装位置//源avi视频的路径String video_path = "D:\\develop\\upload\\02-概述-分库分表是什么.avi";//转换后mp4文件的名称String mp4_name = "02-概述-分库分表是什么.mp4";//转换后mp4文件的路径String mp4_path = "D:\\develop\\upload\\02-概述-分库分表是什么.mp4";//创建工具类对象Mp4VideoUtil videoUtil = new Mp4VideoUtil(ffmpeg_path,video_path,mp4_name,mp4_path);//开始视频转换,成功将返回successString s = videoUtil.generateMp4();System.out.println(s);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/86592.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Centos7.9编写分布式集群大数据系统_自启动脚本---Linux工作笔记058

由于为了方便,系统在启动的时候,设置成系统所有的,集群软件都自动启动,这样,可以减少,运维成本,要不然,这么多,工具,有的还不知道放到什么位置了,一个个去启动,非常麻烦. 首先编辑: 编辑这个文件: 然后编辑这个文件,写上自己,自启动脚本的位置,然后保存 :wq 然后再给这个文件…

【RabbitMQ】golang客户端教程5——使用topic交换器

topic交换器&#xff08;主题交换器&#xff09; 发送到topic交换器的消息不能具有随意的routing_key——它必须是单词列表&#xff0c;以点分隔。这些词可以是任何东西&#xff0c;但通常它们指定与消息相关的某些功能。一些有效的routing_key示例&#xff1a;“stock.usd.ny…

8月11日上课内容 nginx的多实例和动静分离

多实例部署 在一台服务器上有多个tomcat的服务。 配置多实例之前&#xff0c;看单个实例是否访问正常。 1.安装好 jdk 2.安装 tomcat cd /opt tar zxvf apache-tomcat-9.0.16.tar.gz mkdir /usr/local/tomcat mv apache-tomcat-9.0.16 /usr/local/tomcat/tomcat1 cp -a /usr…

利用三维内容编辑器制作VR交互课件,简单好用易上手

随着虚拟现实技术的不断发展&#xff0c;越来越多的教育机构开始尝试将其应用于教育教学中。然而&#xff0c;要实现这一目标并不容易&#xff0c;需要专业的技术支持和开发团队。 为了解决这一问题&#xff0c;广州华锐互动研发了三维内容编辑器&#xff0c;它是一种基于虚拟现…

“掌握类与对象,点亮编程之路“(下)

White graces&#xff1a;个人主页 &#x1f649;专栏推荐:《C语言入门知识》&#x1f649; &#x1f649; 内容推荐:“掌握类与对象&#xff0c;点亮编程之路“(上)&#x1f649; &#x1f439;今日诗词:春风得意马蹄疾&#xff0c;一日看尽长安花&#x1f439; 目录 &…

fork创建多个子进程

fork创建多个子进程 示例代码 fork1.c #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <unistd.h>int main(int argc,char **argv) {int i, j;pid_t pid;for (i 0; i < 3; i){pid fork();if (pid < 0){perror(&q…

Python 11道字典练习题

前言 大家早好、午好、晚好吖 ❤ ~欢迎光临本文章 有字典 dic {“k1”: “v1”, “k2”: “v2”, “k3”: “v3”}&#xff0c;实现以下功能&#xff1a; 1、遍历字典 dic 中所有的key 参考答案&#xff1a; dic {k1: v1,k2:v2,k3:v3}for k in dic.keys():print(k)2、遍历…

Apollo让自动驾驶如此简单

前言&#xff1a; 最近被新能源的电价闹的不行&#xff0c;买了电车的直呼上当了、不香了。但电车吸引人不只是公里油耗低&#xff0c;还有良好的驾车使用感。比如辅助驾驶、甚至是自动驾驶。今天来介绍一个头部自动驾驶平台Apollo&#xff0c;Apollo是一个开源的、自动驾驶的软…

在SpringMVC环境下json字符串与对象转化 配置和对象方法

目录 1..json的使用 字符串与对象转化 2.通过spring配置的形式直接接受json格式字符串转化 1..json的使用 字符串与对象转化 1.导入一个json的jar坐标 <dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</…

el-dialog嵌套,修改内层el-dialog样式(自定义样式)

el-dialog嵌套使用时,内层的el-dialog要添加append-to-body属性 给内层的el-dialog添加custom-class属性,添加自定义类名 <el-dialog:visible.sync"dialogVisible"append-to-bodycustom-class"tree-cesium-container"><span>这是一段信息<…

详细教程:如何搭建废品回收小程序

废品回收是一项环保举措&#xff0c;通过回收和再利用废弃物品&#xff0c;可以减少资源浪费和环境污染。近年来&#xff0c;随着智能手机的普及&#xff0c;小程序成为了推广和运营的重要工具。本文将详细介绍如何搭建一个废品回收小程序。 1. 进入乔拓云网后台 首先&#xf…

深入浅出cgroup

一、什么是cgroup Cgroup是linux内核用来控制系统资源的机制&#xff0c;它将操作系统中的所有进程以组为单位划分&#xff0c;给这一组进程定义对某一类资源特定的访问权限。Cgroup用子系统&#xff08;subsystem&#xff09;来描述所能控制的系统资源&#xff0c;子系统具有…

头条移动端项目Day02—— app端文章查看、静态化freemarker、分布式文件系统minIO

❤ 作者主页&#xff1a;欢迎来到我的技术博客&#x1f60e; ❀ 个人介绍&#xff1a;大家好&#xff0c;本人热衷于Java后端开发&#xff0c;欢迎来交流学习哦&#xff01;(&#xffe3;▽&#xffe3;)~* &#x1f34a; 如果文章对您有帮助&#xff0c;记得关注、点赞、收藏、…

OceanBase X Flink 基于原生分布式数据库构建实时计算解决方案

摘要&#xff1a;本文整理自 OceanBase 架构师周跃跃&#xff0c;在 Flink Forward Asia 2022 实时湖仓专场的分享。本篇内容主要分为四个部分&#xff1a; 分布式数据库 OceanBase 关键技术解读 生态对接以及典型应用场景 OceanBase X Flink 在游戏行业实践 未来展望 点击…

机器学习深度学习——seq2seq实现机器翻译(数据集处理)

&#x1f468;‍&#x1f393;作者简介&#xff1a;一位即将上大四&#xff0c;正专攻机器学习的保研er &#x1f30c;上期文章&#xff1a;机器学习&&深度学习——从编码器-解码器架构到seq2seq&#xff08;机器翻译&#xff09; &#x1f4da;订阅专栏&#xff1a;机…

(el-Form)操作(不使用 ts):Element-plus 中 Form 表单组件校验规则等的使用

Ⅰ、Element-plus 提供的 Form 表单组件与想要目标情况的对比&#xff1a; 1、Element-plus 提供 Form 表单组件情况&#xff1a; 其一、Element-plus 自提供的 Form 代码情况为(示例的代码)&#xff1a; // Element-plus 自提供的代码&#xff1a; // 此时是使用了 ts 语言环…

机器学习深度学习——从编码器-解码器架构到seq2seq(机器翻译)

&#x1f468;‍&#x1f393;作者简介&#xff1a;一位即将上大四&#xff0c;正专攻机器学习的保研er &#x1f30c;上期文章&#xff1a;机器学习&&深度学习——注意力提示、注意力池化&#xff08;核回归&#xff09; &#x1f4da;订阅专栏&#xff1a;机器学习&a…

使用 prometheus client SDK 暴露指标

目录 1. 使用 prometheus client SDK 暴露指标1.1. How Go exposition works1.2. Adding your own metrics1.3. Other Go client features 2. Golang Application monitoring using Prometheus2.1. Metrics and Labels2.2. Metrics Types2.2.1. Counters:2.2.2. Gauges:2.2.3. …

写一个函数返回参数二进制中 1 的个数(c语言三种实现方法)

&#xff08;本文旨在自己做题时的总结&#xff0c;我会给出不同的解法&#xff0c;后面如果碰到新的题目还会加入其中&#xff0c;等于是我自己的题库。 1.写一个函数返回参数二进制中 1 的个数。 比如&#xff1a; 15 0000 1111 4 个 1 方法一&#xff1a; #include…

基于 eclipse-temurin 镜像部署spring boot 应用

基于 eclipse-temurin 镜像部署spring boot 应用 使用场景示例项目 使用场景 在CI流程中&#xff0c;一般都会集成 打包&#xff0c;构建镜像&#xff0c;分发&#xff0c;启动容器之类的流程&#xff1b; 这里提供一个示例&#xff0c;进攻参考 示例项目 项目结构如下 run…