ffmpeg使用及java操作

1.文档

官网: FFmpeg
官方使用文档: ffmpeg Documentation

中文简介: https://www.cnblogs.com/leisure_chn/p/10297002.html

函数及时间: ffmpeg日记1011-过滤器-语法高阶,逻辑,函数使用_ffmpeg gte(t,2)-CSDN博客

java集成ffmpeg: SpringBoot集成ffmpeg实现视频转码播放_jave-all-deps-CSDN博客 

2.命令

快速复制视频片段
ffmpeg -ss 00:00:40 -i test.mp4 -to 00:01:00 -c:v copy -c:a copy  testOutput40.mp4复制视频片段,并调整视频质量,crf一般为23,crf越大压缩越厉害,质量下降越多
ffmpeg -i test.mp4 -ss 00:30 -to 00:50 -c:v libx264 -crf 23 newTest1.mp4调整视频分辨率(调整的分辨率超过原来的,不能提升画质)
ffmpeg -i test.mp4 -vf scale=432:240 video_240p.mp4 -hide_banner
ffmpeg -i test.mp4 -vf scale=-1:240 video_240p.mp4 -hide_banner加水印(10:10水印距离左上角的像素距离)
ffmpeg -i test.mp4 -i used100.png -filter_complex "overlay=10:10" testOutputWater.mp4--保真加水印,不怎么改变视频编码及质量
ffmpeg -i test.mp4 -i used100.png -filter_complex "overlay=10:10" -c:v libx264 -c:a copy testOutputWater2.mp4--视频2秒后开始显示水印,gte(t\,2)
ffmpeg -i test.mp4 -vf "movie=used100.png[logo];[in][logo]overlay=x='if(gte(t\,2)\,0\,NAN)'" testOutputWater6.mp4--在指定时间范围(20-30秒)显示水印,between(t\,20\,30)
ffmpeg -i test.mp4 -vf "movie=used100.png[logo];[in][logo]overlay=x='if(between(t\,20\,30)\,0\,NAN)'" testOutputWater9.mp4加硬字幕
ffmpeg -i test.mp4 -vf subtitles=test.srt mp4_add_captions1.mp4

3.java代码

        maven依赖,使用集成的ffmpeg程序,缺点是打成的jar包很大,优点是不需要手动安装ffmpeg

        <!--   音视频   --><dependency><groupId>ws.schild</groupId><artifactId>jave-all-deps</artifactId><version>3.0.1</version><exclusions><!--  排除windows 32位系统      --><exclusion><groupId>ws.schild</groupId><artifactId>jave-nativebin-win32</artifactId></exclusion><!--  排除linux 32位系统      --><exclusion><groupId>ws.schild</groupId><artifactId>jave-nativebin-linux32</artifactId></exclusion><!-- 排除Mac系统--><exclusion><groupId>ws.schild</groupId><artifactId>jave-nativebin-osx64</artifactId></exclusion></exclusions></dependency>

          第二种方式,不引入集成的ffmpeg,手动在程序运行的服务器上安,优点是打成的jar包较小,关于如何手动在服务器上配置ffmpeg,请见附录2

        <!--音视频操作--><dependency><groupId>ws.schild</groupId><artifactId>jave-core</artifactId><version>3.0.1</version></dependency>

        工具类

package mis.shared.file;import lombok.extern.slf4j.Slf4j;
import ws.schild.jave.Encoder;
import ws.schild.jave.EncoderException;
import ws.schild.jave.MultimediaObject;
import ws.schild.jave.encode.AudioAttributes;
import ws.schild.jave.encode.EncodingAttributes;
import ws.schild.jave.encode.VideoAttributes;
import ws.schild.jave.info.MultimediaInfo;
import ws.schild.jave.process.ProcessWrapper;
import ws.schild.jave.process.ffmpeg.DefaultFFMPEGLocator;import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;/*** 音视频操作** @since 2024/1/22*/
@Slf4j
public class FfmpegUtil {/*** 通过本地路径获取多媒体文件信息(宽,高,时长,编码等)** @param localPath 文件路径* @return MultimediaInfo 媒体对象,包含 (宽,高,时长,编码等)*/public static MultimediaInfo GetMediaInfo(String localPath) {MultimediaInfo multimediaInfo = null;try {multimediaInfo = new MultimediaObject(new File(localPath)).getInfo();} catch (EncoderException e) {log.error("获取媒体信息异常!", e);}return multimediaInfo;}/*** 修改视频分辨率,修改分辨率超过原视频,不能提高画质* 标清SD(Standard Definition) 宽 x 高* 480p 640x480 704x480 720x480 848x480* 高清 HD(High Definition)* 720p 960x720 1280x720* 1080p 1440x1080 1920x1080* 超高清UHD(Ultra High Definition)* 4k 4096×3112 4096*2160** @param inputPath  视频来源地址* @param outputPath 输出视频地址* @param width      宽度* @param height     高度*/public static boolean ChangeScale(String inputPath, String outputPath, int width, int height) {ProcessWrapper ffmpeg = null;try {if (new File(outputPath).exists()) {log.error("目标文件已存在,outputPath:{}", outputPath);return false;}ffmpeg = new DefaultFFMPEGLocator().createExecutor();ffmpeg.addArgument("-i");ffmpeg.addArgument(inputPath);ffmpeg.addArgument("-vf");ffmpeg.addArgument("scale=" + width + ":" + height);ffmpeg.addArgument("-c:a");ffmpeg.addArgument("copy");ffmpeg.addArgument(outputPath);long start = System.currentTimeMillis();//异步执行ffmpeg.execute();//等待完成WaitFfmpegFinish(ffmpeg);log.info("花费时间:{}", System.currentTimeMillis() - start);return true;} catch (Exception e) {log.error("修改视频画质异常", e);} finally {if (ffmpeg != null) {ffmpeg.destroy();}}return false;}/*** 复制视频片段** @param inputPath  视频来源地址* @param outputPath 输出视频地址* @param startTime  开始时间,01:02:03在视频的第1小时第2分钟第3秒处* @param endTime    结束时间,格式同startTime*/public static boolean CopyVideo(String inputPath, String outputPath, String startTime, String endTime) {ProcessWrapper ffmpeg = null;try {if (new File(outputPath).exists()) {log.error("目标文件已存在,outputPath:{}", outputPath);return false;}ffmpeg = new DefaultFFMPEGLocator().createExecutor();ffmpeg.addArgument("-ss");ffmpeg.addArgument(startTime);ffmpeg.addArgument("-i");ffmpeg.addArgument(inputPath);ffmpeg.addArgument("-to");ffmpeg.addArgument(endTime);ffmpeg.addArgument("-c:v");ffmpeg.addArgument("copy");ffmpeg.addArgument("-c:a");ffmpeg.addArgument("copy");ffmpeg.addArgument(outputPath);long start = System.currentTimeMillis();//异步执行ffmpeg.execute();//等待完成WaitFfmpegFinish(ffmpeg);log.info("花费时间:{}", System.currentTimeMillis() - start);return true;} catch (Exception e) {log.error("复制视频片段异常", e);} finally {if (ffmpeg != null) {ffmpeg.destroy();}}return false;}/*** 视频格式转换为mp4*/public static boolean FormatToMp4(String localPath, String outputPath) {try {File target = new File(outputPath);if (target.exists()) {log.error("目标文件已存在,outputPath:{}", outputPath);return false;}MultimediaObject multimediaObject = new MultimediaObject(new File(localPath));EncodingAttributes attributes = new EncodingAttributes();// 设置视频的音频参数AudioAttributes audioAttributes = new AudioAttributes();attributes.setAudioAttributes(audioAttributes);// 设置视频的视频参数VideoAttributes videoAttributes = new VideoAttributes();// 设置帧率videoAttributes.setFrameRate(25);attributes.setVideoAttributes(videoAttributes);// 设置输出格式attributes.setOutputFormat("mp4");Encoder encoder = new Encoder();encoder.encode(multimediaObject, target, attributes);return true;} catch (Exception e) {log.error("视频转换异常!", e);return false;}}/*** 获取视频缩略图* 获取视频第0秒的第一帧图片*/public static boolean GetThumbnail(String localPath, String outputPath) {ProcessWrapper ffmpeg = null;try {File target = new File(outputPath);if (target.exists()) {log.error("目标文件已存在,outputPath:{}", outputPath);return false;}ffmpeg = new DefaultFFMPEGLocator().createExecutor();ffmpeg.addArgument("-i");ffmpeg.addArgument(localPath);ffmpeg.addArgument("-ss");ffmpeg.addArgument("0");ffmpeg.addArgument(outputPath);ffmpeg.execute();//等待执行完成WaitFfmpegFinish(ffmpeg);} catch (Exception e) {log.error("获取视频缩略图异常", e);return false;} finally {if (ffmpeg != null) {ffmpeg.destroy();}}return true;}/*** 等待命令执行完成*/private static void WaitFfmpegFinish(ProcessWrapper processWrapper) throws Exception {//输出执行情况不是通过inputStream,而是errorStreamtry (BufferedReader br = new BufferedReader(new InputStreamReader(processWrapper.getErrorStream()))) {String processInfo;while ((processInfo = br.readLine()) != null) {//打印执行过程log.trace(processInfo);}} catch (Exception e) {log.error("等待执行完成异常!", e);}}public static void main(String[] args) {String inputFile = "e://develop//tmp//test.mp4";String outputFile = "e://develop//tmp//testOutput14.mp4";//复制视频指定片段CopyVideo(inputFile, outputFile, "00:00:10", "00:01:00");//获取媒体信息// MultimediaInfo multimediaInfo = GetMediaInfo(inputFile);// log.info("文件信息:{}", multimediaInfo);// VideoSize videoSize = multimediaInfo.getVideo().getSize();// log.info("文件信息,宽:{},高:{}", videoSize.getWidth(), videoSize.getHeight());//修改视频画质//ChangeScale(inputFile, outputFile, 640, 480);}}

附录1

         字幕test.srt

1
00:00:20,000 --> 00:00:30,000
这是视频第20秒到30秒将显示的字幕2
00:00:50,000 --> 00:00:60,000
这是视频第50秒到60秒将显示的字幕

附录2

        关于ffmpeg在服务器上的位置,参考如下代码

  public DefaultFFMPEGLocator() {String os = System.getProperty("os.name").toLowerCase();boolean isWindows = os.contains("windows");boolean isMac = os.contains("mac");LOG.debug("Os name is <{}> isWindows: {} isMac: {}", os, isWindows, isMac);// Dir FolderFile dirFolder = new File(System.getProperty("java.io.tmpdir"), "jave/");if (!dirFolder.exists()) {LOG.debug("Creating jave temp folder to place executables in <{}>", dirFolder.getAbsolutePath());dirFolder.mkdirs();} else {LOG.debug("Jave temp folder exists in <{}>", dirFolder.getAbsolutePath());}// -----------------ffmpeg executable export on disk.-----------------------------String suffix = isWindows ? ".exe" : (isMac ? "-osx" : "");String arch = System.getProperty("os.arch");// FileFile ffmpegFile = new File(dirFolder, "ffmpeg-" + arch + "-" + Version.getVersion() + suffix);LOG.debug("Executable path: {}", ffmpegFile.getAbsolutePath());// Check the version of existing .exe fileif (ffmpegFile.exists()) {// OK, already presentLOG.debug("Executable exists in <{}>", ffmpegFile.getAbsolutePath());} else {LOG.debug("Need to copy executable to <{}>", ffmpegFile.getAbsolutePath());copyFile("ffmpeg-" + arch + suffix, ffmpegFile);}// Need a chmod?if (!isWindows) {try {Runtime.getRuntime().exec(new String[] {"/bin/chmod", "755", ffmpegFile.getAbsolutePath()});} catch (IOException e) {LOG.error("Error setting executable via chmod", e);}}// Everything seems okaypath = ffmpegFile.getAbsolutePath();if (ffmpegFile.exists()){LOG.debug("ffmpeg executable found: {}", path);}else{LOG.error("ffmpeg executable NOT found: {}", path);}}

       windows环境,打开cmd窗口,执行echo %TEMP%获取临时文件夹,打开临时文件夹,创建子文件夹jave(最终路径例子C:\Users\TN\AppData\Local\Temp\jave)

        下载ws.schild的maven对应系统jar包,并解压jave-nativebin-win64-3.0.1,找到里面的ffmpeg-amd64.exe复制到上面的目录下

         linux通过脚本获取默认目录,原理是通过编译运行FfmpegHelper.java获得

#!/bin/bashcd /tmp# download 
if [ -e "/tmp/FfmpegHelper.java" ]
thenecho "FfmpegHelper.java already exist!"
elseecho "FfmpegHelper.java does not exist,start download"wget https://fs-im-kefu.7moor-fs1.com/29397395/4d2c3f00-7d4c-11e5-af15-41bf63ae4ea0/1705980395189/FfmpegHelper.java
fi# compile
if [ -e "/tmp/FfmpegHelper.class" ]
thenecho "FfmpegHelper.class already exist!"
elseecho "FfmpegHelper.class does not exist,start compile"javac FfmpegHelper.java
fi# run
java FfmpegHelper# clean
rm -rf /tmp/FfmpegHelper.class
rm -rf /tmp/FfmpegHelper.java

        FfmpegHelper.java

import java.io.File;public class FfmpegHelper {public static String GetDefaultFFMPEGPath() {return new File(System.getProperty("java.io.tmpdir"), "jave/").getAbsolutePath();}public static void main(String[] args) {String defaultFFMPEGPath = GetDefaultFFMPEGPath();System.out.println(defaultFFMPEGPath);}}

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

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

相关文章

科技云报道:金融大模型落地,还需跨越几重山?

科技云报道原创。 时至今日&#xff0c;大模型的狂欢盛宴仍在持续&#xff0c;而金融行业得益于数据密集且有强劲的数字化基础&#xff0c;从一众场景中脱颖而出。 越来越多的公司开始布局金融行业大模型&#xff0c;无论是乐信、奇富科技、度小满、蚂蚁这样的金融科技公司&a…

深度学习如何弄懂那些难懂的数学公式?是否需要学习数学?

经过1~2年的学习&#xff0c;我觉得还是需要数学有一定认识&#xff0c;重新捡起高等数学、概率与数理、线代等这几本&#xff0c;起码基本微分方程、求导、对数、最小损失等等还是会用到。 下面给出几个链接&#xff0c;可以用于平时充电学习。 知乎上的&#xff1a; 机器学…

计算机毕业设计 基于SpringBoot的律师事务所案件管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

git merge和git rebase区别

具体详情 具体常见如下&#xff0c;假设有master和change分支&#xff0c;从同一个节点分裂&#xff0c;随后各自进行了两次提交commit以及修改。随后即为change想合并到master分支中&#xff0c;但是直接git commit和git push是不成功的&#xff0c;因为分支冲突了【master以…

上位机图像处理和嵌入式模块部署(流程)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 前面我们说过&#xff0c;传统图像处理的方法&#xff0c;一般就是pccamera的处理方式。camera本身只是提供基本的raw data数据&#xff0c;所有的…

基于ADAS的车道线检测算法matlab仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 4.1 图像预处理 4.2 车道线特征提取 4.3 车道线跟踪 5.完整工程文件 1.课题概述 基于ADAS的车道线检测算法,通过hough变换和边缘检测方法提取视频样板中的车道线&#xff0c;然后根据车道线的弯曲情况…

Linux/Mac 命令行工具 tree 开发项目结构可以不用截图了 更方便 更清晰 更全

tree 是一个命令行工具&#xff0c;用于以树形结构显示文件系统目录的内容。它可用于列出指定目录下的所有文件和子目录&#xff0c;以及它们的层次关系。tree 命令在许多操作系统中都可用&#xff0c;包括Unix、Linux和macOS。 效果如下&#xff1a; 一、安装 linux # De…

Prometheus+Grafana监控Mysql数据库

Promethues Prometheus https://prometheus.io Prometheus是一个开源的服务监控系统&#xff0c;它负责采集和存储应用的监控指标数据&#xff0c;并以可视化的方式进行展示&#xff0c;以便于用户实时掌握系统的运行情况&#xff0c;并对异常进行检测。因此&#xff0c;如何…

Spring Boot3整合knife4j(swagger3)

目录 1.前置条件 2.导依赖 3.配置 1.前置条件 已经初始化好一个spring boot项目且版本为3X&#xff0c;项目可正常启动。 作者版本为3.2.2最新版 2.导依赖 knife4j官网&#xff1a; Knife4j 集Swagger2及OpenAPI3为一体的增强解决方案. | Knife4j (xiaominfo.com)http…

R语言简介

1.R语言 R语言是一种数学编程语言&#xff0c;主要用于统计分析、绘图和数据挖掘。 2.R语言特点 免费、开源&#xff0c;兼容性好&#xff08;Windows、MacOS或Linux)。具有多种数据类型&#xff0c;如向量、矩阵、因子、数据集等常用数据结构。多用于交互式数据分析&#x…

股权众筹模式介绍(下)

3、线上线下两段式投资 对于已经成成立并运营的企业来说&#xff0c;由于《证券法》明确规定&#xff0c;向“不特定对象发行证券”以及“向特定对象发行证券累计超过200人”的行为属于公开发行证券&#xff0c;必须通过证监会核准&#xff0c;由证券公司承销。这些规定限定了…

RTDETR 引入 UniRepLKNet:用于音频、视频、点云、时间序列和图像识别的通用感知大卷积神经网络 | DRepConv

大卷积神经网络(ConvNets)近来受到了广泛研究关注,但存在两个未解决且需要进一步研究的关键问题。1)现有大卷积神经网络的架构主要遵循传统ConvNets或变压器的设计原则,而针对大卷积神经网络的架构设计仍未得到解决。2)随着变压器在多个领域的主导地位,有待研究ConvNets…

小程序商城 免 费 搭 建之java商城 电子商务Spring Cloud+Spring Boot+二次开发+mybatis+MQ+VR全景+b2b2c

java SpringCloud版本b2b2c鸿鹄云商平台全套解决方案 使用技术&#xff1a; Spring CloudSpring BootMybatis微服务服务监控可视化运营 B2B2C平台&#xff1a; 平台管理端(包含自营) 商家平台端(多商户入驻) PC买家端、手机wap/公众号买家端 微服务&#xff08;30个通用…

Unity中URP下的SimpleLit的 BlinnPhong高光反射计算

文章目录 前言一、回顾Blinn-Phong光照模型1、Blinn-Phong模型&#xff1a; 二、URP下的SimpleLit的 BlinnPhong1、输入参数2、程序体计算 前言 在上篇文章中&#xff0c;我们分析了 URP下的SimpleLit的 Lambert漫反射计算。 Unity中URP下的SimpleLit的 Lambert漫反射计算 我…

Java基于沙箱环境实现支付宝支付

一、支付宝沙箱环境介绍 沙箱环境是支付宝开放平台为开发者提供的安全低门槛的测试环境&#xff0c;开发者在沙箱环境中调用接口无需具备所需的商业资质&#xff0c;无需绑定和开通产品&#xff0c;同时不会对生产环境中的数据造成任何影响。合理使用沙箱环境&#xff0c;可以…

Android14实战:调整A2DP音量曲线(五十三)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒体系统工程师系列【原创干货持续更新中……】🚀 人生格言: 人生从来没有捷径,只…

【Linux install】Ubuntu和win双系统安装及可能遇到的所有问题

文章目录 1.前期准备1.1 制作启动盘1.2关闭快速启动、安全启动、bitlocker1.2.1 原因1.2.2 进入BIOSshell命令行进入BIOSwindows设置中高级启动在开机时狂按某个键进入BIOS 1.2.3 关闭Fast boot和Secure boot 1.3 划分磁盘空间1.3.1 查看目前的虚拟内存大小 2.开始安装2.1 使用…

大模型的学习路线图推荐—多维度深度分析【云驻共创】

&#x1f432;本文背景 近年来&#xff0c;随着深度学习技术的迅猛发展&#xff0c;大模型已经成为学术界和工业界的热门话题。大模型具有数亿到数十亿的参数&#xff0c;这使得它们在处理复杂任务时表现得更为出色&#xff0c;但同时也对计算资源和数据量提出了更高的要求。 …

源 “MySQL 5.7 Community Server“ 的 GPG 密钥已安装,但是不适用于此软件包。请检查源的公钥 URL 是否配置正确

Is this ok [y/d/N]: y Downloading packages: 警告&#xff1a;/var/cache/yum/x86_64/7/mysql57-community/packages/mysql-community-server-5.7.44-1.el7.x86_64.rpm: 头V4 RSA/SHA256 Signature, 密钥 ID 3a79bd29: NOKEY 从 file:///etc/pki/rpm-gpg/RPM-GPG-KEY-mysql 检…

canvas绘制旋转的椭圆花

查看专栏目录 canvas实例应用100专栏&#xff0c;提供canvas的基础知识&#xff0c;高级动画&#xff0c;相关应用扩展等信息。canvas作为html的一部分&#xff0c;是图像图标地图可视化的一个重要的基础&#xff0c;学好了canvas&#xff0c;在其他的一些应用上将会起到非常重…