Java 视频处理:基于 MD5 校验秒传及 ffmpeg 切片合并的实现

本文介绍两种网络技术实现方法。一是 MD5 校验秒传,服务器端用数据库记上传文件 MD5 值及存储路径,Java 代码接收客户端 MD5 值并查询校验,返回状态码。二是用 ffmpeg 切片视频成 m3u8 上传,异步合并文件实现视频按需加载。
在这里插入图片描述

1. 通过MD5校验实现秒传

服务器端MD5校验

  1. 数据库存储
    服务器端需数据库(如 MySQL、MongoDB 等)记录上传文件 MD5 值及存储路径。以 MySQL 为例,创建简单表存储相关信息。表结构中,md5_value存文件 MD5 值,file_path存服务器端存储路径,upload_time记录文件上传时间。
CREATE TABLE uploaded_files (id INT AUTO_INCREMENT PRIMARY KEY,md5_value VARCHAR(32) NOT NULL UNIQUE,file_path VARCHAR(255) NOT NULL,upload_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
  1. 校验逻辑实现
    Java服务器端代码示例:接收客户端 MD5 值并校验(用 Spring Boot 框架简化示例,实际应用可依具体框架和需求调整)。代码中接收客户端传来的 MD5 值在数据库查询校验。查到记录则文件已存在,返回 200 状态码表示秒传成功;未查到返回 404 表示需正常上传;查询出错返回 500 表示服务器内部错误。
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;@SpringBootApplication
@RestController
public class FileServerApp {private static final String JDBC_URL = "jdbc:mysql://localhost:3306/your_database_name?useSSL=false&serverTimezone=UTC";private static final String JDBC_USERNAME = "your_username";private static final String JDBC_PASSWORD = "your_password";public static void main(String[] args) {SpringApplication.run(FileServerApp.class, args);}@GetMapping("/checkFile")public ResponseEntity<String> checkFile(@RequestParam("md5") String md5) {try (Connection connection = DriverManager.getConnection(JDBC_URL, JDBC_USERNAME, JDBC_PASSWORD);PreparedStatement preparedStatement = connection.prepareStatement("SELECT file_path FROM uploaded_files WHERE md5_value =?")) {preparedStatement.setString(1, md5);ResultSet resultSet = preparedStatement.executeQuery();if (resultSet.next()) {// 文件已存在,返回200状态码return new ResponseEntity<>("文件已存在", HttpStatus.OK);} else {// 文件不存在,返回404状态码return new ResponseEntity<>("文件不存在", HttpStatus.NOT_FOUND);}} catch (SQLException e) {e.printStackTrace();// 数据库查询出错,返回500状态码return new ResponseEntity<>("服务器内部错误", HttpStatus.INTERNAL_SERVER_ERROR);}}
}

2. 用 ffmpeg 将视频切片成 m3u8 上传,采用异步合并文件实现视频按需加载

视频切割

  1. 参数调整
    前面切割视频示例仅设常见参数,如视频编码格式(-c:v libx264)、音频编码格式(-c:a aac)、切片时长(-hls_time 10)和列表大小(-hls_list_size 0)。实际应用中或需依具体需求调整这些参数,比如:

    • 视频分辨率:要支持多种分辨率视频播放,可添加不同参数设置生成不同分辨率视频切片集合,在 m3u8 文件中组织,实现自适应分辨率播放。如添加-s:v 1280x720-s:v 640x360等参数分别生成高清和标清视频切片。
    • 码率设置:根据网络状况和目标设备性能,需设置不同视频码率,可通过参数如-b:v 2000k实现不同码率视频切片生成。
  2. 错误处理细化
    仅依process.waitFor()返回值判断切割不足。实际应用中应获取ffmpeg执行输出信息定位问题。以下是修改后示例,读取ffmpeg标准输出和错误输出信息处理切割问题。

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;public class VideoSliceUtil {public static void sliceVideo(File videoFile, String outputDir) {try {String ffmpegPath = "ffmpeg"; // 根据实际安装路径修改String command = ffmpegPath + " -i " + videoFile.getAbsolutePath() + " -c:v libx264 -c:a aac -f hls -hls_time 10 -hls_list_size 0 " + outputDir + "/video.m3u8";Process process = Runtime.getRuntime().exec(command);// 读取标准输出和标准错误输出信息InputStream stdout = process.getInputStream();InputStream stderr = process.getErrorStream();BufferedReader stdoutReader = new BufferedReader(new InputStreamReader(stdout));BufferedReader stderrReader = new BufferedReader(new InputStreamReader(stderr));List<String> stdoutMessages = new ArrayList<>();List<String> stderrMessages = new ArrayList<>();String line;while ((line = stdoutReader.readLine())!= null) {stdoutMessages.add(line);}while ((line = stderrReader.readLine())!= null) {stderrMessages.add(line);}int exitCode = process.waitFor();if (exitCode == 0) {System.out.println("视频切割成功");if (!stdoutMessages.isEmpty()) {System.out.println("标准输出信息:");for (String msg : stdoutMessages) {System.out.println(msg);}}} else {System.out.println("视频切割失败");if (!stderrMessages.isEmpty()) {System.out.println("标准错误输出信息:");for (String msg : stderrMessages) {System.out.println(msg);}}}// 关闭流stdoutReader.close();stderrReader.close();stdout.close();stderr.close();} catch (Exception e) {e.printStackTrace();}}
}

异步合并文件

  1. 具体合并逻辑实现
    使用FFmpegFrameRecorder库合并视频片段。假设切割所得片段在指定目录且 m3u8 文件已正确生成。先创建FFmpegFrameRecorder对象,设置视频、音频编码格式及输出文件格式。遍历视频片段,用FrameGrabber读取帧,通过recorder记录到合并文件中。
import java.io.File;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.ffmpeg.global.avutil;
import org.bytedeco.ffmpeg.global.swscale;
import org.bytedeco.javacv.FFmpegFrameRecorder;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.FrameGrabber;
import org.bytedeco.javacv.OpenCVFrameGrabber;public class FileMergeAsync {public static void mergeFilesAsync(final File[] filesToMerge, final String outputFile) {ExecutorService executor = Executors.newSingleThreadExecutor();executor.submit(new Runnable() {@Overridepublic void run() {try {// 创建FFmpegFrameRecorder对象用于合并视频FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(outputFile, -1);recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);recorder.setAudioCodec(avutil.AV_CODEC_ID_AAC);recorder.setFormat("mp4");recorder.start();// 遍历每个视频片段进行合并for (File file : filesToMerge) {FrameGrabber grabber = new OpenCVFrameGrabber(file);grabber.start();Frame frame;while ((frame = grabber.read())!= null) {recorder.record(frame);}grabber.stop();}recorder.stop();System.out.println("文件合并成功");} catch (Exception e) {e.printStackTrace();System.out.println("文件合并失败");} finally {executor.shutdown();}}});}
}
  1. 资源管理与优化
    合并文件时涉及多个对象创建与使用,如FFmpegFrameRecorderFrameGrabber等,需注意资源管理与优化。用后及时调用stop()释放资源,避免内存泄漏。对可能的异常,在异常处理代码中正确关闭和释放资源。

  2. 异步处理的监控与反馈
    前面异步合并文件示例仅提交任务后打印成功或失败消息。实际应用中需对异步任务深入监控并提供更多反馈。可通过添加回调函数或用异步任务监控框架了解进度、异常等情况并反馈给相关方。

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

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

相关文章

JEL分类号

JEL分类系统&#xff0c;是美国经济学会“经济文献杂志”(《经济文献杂志》)所创立的对经济学文献的主题分类系统&#xff0c;并被现代西方经济学界广泛采用。 该分类方法主要采用开头的一个英文字母与随后的两位阿拉伯数字一起对经济学各部类进行“辞书式”编码分类。 https:…

[Qt]常用控件介绍-多元素控件-QListWidget、QTableWidget、QQTreeWidget

目录 1.多元素控件介绍 2.ListWidget控件 属性 核心方法 核心信号 细节 Demo&#xff1a;编辑日程 3.TableWidget控件 核心方法 QTableWidgetItem核心信号 QTableWidgetItem核心方法 细节 Demo&#xff1a;编辑学生信息 4.TreeWidget控件 核心方法 核心信号…

【王树森搜索引擎技术】概要01:搜索引擎的基本概念

1. 基本名词 query&#xff1a;查询词SUG&#xff1a;搜索建议文档&#xff1a;搜索结果标签/筛选项 文档单列曝光 文档双列曝光 2. 曝光与点击 曝光&#xff1a;用户在搜索结果页上看到文档&#xff0c;就算曝光文档点击&#xff1a;在曝光后&#xff0c;用户点击文档&…

Vulnhub-Tr0ll靶机笔记

Tr0ll靶机笔记 概述 靶机地址&#xff1a;https://www.vulnhub.com/entry/tr0ll-1,100/ 这台靶机比较简单&#xff0c;包含ftp的渗透&#xff0c;pcap流量包的分析&#xff0c;常规的web渗透和系统内核提权。让我们开始吧 Hack it&#xff01; 一、nmap扫描 1、端口扫描 …

uniapp 微信小程序 editor 富文本编辑器

<view class"inp boxsizing"><view class"contentBox"><!-- 富文本编辑器 --><view classwrapper><view classtoolbar tap"format"><view :class"formats.bold ? ql-active : " class"iconfon…

Java定时任务不明原因挂掉(定时任务挂掉)以及建议

在Java企业级开发中&#xff0c;Spring框架的定时任务功能&#xff08;通常通过Scheduled注解实现&#xff09;因其易用性和灵活性而备受青睐。然而&#xff0c;当这些定时任务在生产环境中莫名停止时&#xff0c;往往会让开发者头疼不已。 一、常见原因剖析 1.线程或资源耗尽…

USB 驱动开发 --- Gadget 驱动框架梳理(一)

本文由 Linux 内核文档翻译与总结而来&#xff0c;个人学习笔记仅供参考。 Gadget 框架 在 USB 协议交互过程中&#xff0c;角色定义&#xff1a; the device driver is the master (or “client driver”) Linux 内核中称为 HCD(Host Controller Driver)&#xff0c;负责与 …

python实现pdf转word和excel

一、引言   在办公中&#xff0c;我们经常遇收到pdf文件格式&#xff0c;因为pdf格式文件不易修改&#xff0c;当我们需要编辑这些pdf文件时&#xff0c;经常需要开通会员或收费功能才能使用编辑功能。今天&#xff0c;我要和大家分享的&#xff0c;是如何使用python编程实现…

Jenkins-基于Role的鉴权机制

jenkins自带了一些全局性的安全配置。 但无法通过job等相对细粒度的来控制使用者的权限。但它可以借助相关的插件实现细颗粒的权限控制。 插件&#xff1a; Role-based Authorization Strategy 需要在configure global security中配置授权策略如下&#xff1a; 保存后&#x…

差分(前缀和的逆运算)

作用&#xff1a; 在 [ l ,r ] 数组中&#xff0c;对全部数字c 思路 原数组a 构造差分数组b使得a[i]b1b2b3...bi; a数组是b数组的前缀和,b1b2b3...bnan b[i] a[i]-a[i-1]; 在d21,那在前缀和时&#xff0c;这些a都1 在数组中&#xff0c;要l~r这段数c 在l处c后&#xff0c…

【转】厚植根基,同启新程!一文回顾 2024 OpenHarmony 社区年度工作会议精彩瞬间

在数字化浪潮奔腾不息的今天&#xff0c;开源技术已成为推动科技创新与产业发展的强大引擎。2025年1月10日-11日&#xff0c;OpenAtom OpenHarmony&#xff08;开放原子开源鸿蒙&#xff0c;以下简称“OpenHarmony”或“开源鸿蒙”&#xff09;社区2024年度工作会议于深圳盛大启…

flutter 常用UI组件

文章目录 1. Toast 文本提示框oktoastbot_toast2. loading 加载窗flutter_easyloading3. 对话框gex dialog4.下拉刷新pull_to_refresh5. pop 窗custom_pop_up_menu6. pin code 密码框pinput7. 二维码qr_flutter8. swiper 滚动组件carousel_sliderflutter_swiper_view9. Badge 角…

重学SpringBoot3-Spring Retry实践

更多SpringBoot3内容请关注我的专栏&#xff1a;《SpringBoot3》 期待您的点赞??收藏评论 重学SpringBoot3-Spring Retry实践 1. 简介2. 环境准备3. 使用方式 3.1 注解方式 基础使用自定义重试策略失败恢复机制重试和失败恢复效果注意事项 3.2 编程式使用3.3 监听重试过程 监…

爬虫第二篇

太聪明了怎么办&#xff1f;那就&#xff0c;给脑子灌点水&#xff01;&#xff01; 本篇文章我们来简单讲一下如何爬取mv,也就是歌曲视频&#xff0c;那么我们进入正题。 由于上次拿网易云开了刀&#xff0c;那么这次我们拿酷狗开刀。 还是进入上次讲过的页面 注意&#xff…

【ArcGIS微课1000例】0140:总览(鹰眼)、放大镜、查看器的用法

文章目录 一、总览工具二、放大镜工具三、查看器工具ArcGIS中提供了三种局部查看的工具: 总览(鹰眼)、放大镜、查看器,如下图所示,本文讲述这三种工具的使用方法。 一、总览工具 为了便于效果查看与比对,本实验采用全球影像数据(位于配套实验数据包中的0140.rar中),加…

快手极速版如何查找ip归属地?怎么关掉

在数字化时代&#xff0c;个人隐私的保护成为了广大用户关注的焦点。快手极速版作为一款备受欢迎的短视频应用&#xff0c;其IP归属地的显示与关闭功能自然也成了用户热议的话题。本文将详细介绍如何在快手极速版中查找IP归属地以及如何关闭IP属地显示&#xff0c;帮助用户更好…

MQ消息队列

1、消息队列特点 2、RabbitMQ

Web自动化:Cypress 测试框架概述

&#x1f345; 点击文末小卡片 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 Cypress 测试框架概述 1.1 Cypress 默认文件结构 在Cypress安装完成后&#xff0c;其生成的默认文件目录如下所示&#xff1a; 1.1.1 Fixtures Fixture又称之为测…

基于SSM汽车美容管家【提供源码+答辩PPT+文档+项目部署】(高质量源码,可定制,提供文档,免费部署到本地)

作者简介&#xff1a;✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流。✌ 主要内容&#xff1a;&#x1f31f;Java项目、Python项目、前端项目、PHP、ASP.NET、人工智能…

tlias部门管理-新增部门-接口开发

需求 点击 "新增部门" 的按钮之后&#xff0c;弹出新增部门表单&#xff0c;填写部门名称之后&#xff0c;点击确定之后&#xff0c;保存部门数据。 了解了需求之后&#xff0c;我们再看看接口文档中&#xff0c;关于新增部门的接口的描述&#xff0c;然后根据接口…