java通过url获取视频时长(无需下载文件)

 1、导入架包

        <!-- jave 核心依赖 --><dependency><groupId>ws.schild</groupId><artifactId>jave-core</artifactId><version>2.4.6</version></dependency><!-- 根据不同操作系统引入不同FFmpeg包 --><!-- window32位 FFmpeg --><dependency><groupId>ws.schild</groupId><artifactId>jave-native-win32</artifactId><version>2.4.6</version></dependency><!-- window64位 FFmpeg --><dependency><groupId>ws.schild</groupId><artifactId>jave-native-win64</artifactId><version>2.4.6</version></dependency><!-- linux64位 FFmpeg --><dependency><groupId>ws.schild</groupId><artifactId>jave-native-linux64</artifactId><version>2.4.6</version></dependency><!-- macos64位 FFmpeg --><dependency><groupId>ws.schild</groupId><artifactId>jave-native-osx64</artifactId><version>2.4.6</version></dependency>

2、创建FFmpegFileInfo类(类的位置ws.schild.jave)

 

package ws.schild.jave;import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;public class FFmpegFileInfo {private static final Log LOG = LogFactory.getLog(MultimediaObject.class);private static final Pattern SIZE_PATTERN = Pattern.compile("(\\d+)x(\\d+)", 2);private static final Pattern FRAME_RATE_PATTERN = Pattern.compile("([\\d.]+)\\s+(?:fps|tbr)", 2);private static final Pattern BIT_RATE_PATTERN = Pattern.compile("(\\d+)\\s+kb/s", 2);private static final Pattern SAMPLING_RATE_PATTERN = Pattern.compile("(\\d+)\\s+Hz", 2);private static final Pattern CHANNELS_PATTERN = Pattern.compile("(mono|stereo|quad)", 2);private final FFMPEGLocator locator;private File inputFile;public FFmpegFileInfo(File input) {this.locator = new DefaultFFMPEGLocator();this.inputFile = input;}public File getFile() {return this.inputFile;}public void setFile(File file) {this.inputFile = file;}public FFmpegFileInfo(File input, FFMPEGLocator locator) {this.locator = locator;this.inputFile = input;}public MultimediaInfo getInfo(String url) throws InputFormatException, EncoderException {FFMPEGExecutor ffmpeg = this.locator.createExecutor();ffmpeg.addArgument("-i");ffmpeg.addArgument(url);try {ffmpeg.execute();} catch (IOException var9) {throw new EncoderException(var9);}MultimediaInfo var4;try {RBufferedReader reader = new RBufferedReader(new InputStreamReader(ffmpeg.getErrorStream()));var4 = this.parseMultimediaInfo(this.inputFile, reader);} finally {ffmpeg.destroy();}return var4;}private MultimediaInfo parseMultimediaInfo(File source, RBufferedReader reader) throws InputFormatException, EncoderException {Pattern p1 = Pattern.compile("^\\s*Input #0, (\\w+).+$\\s*", 2);Pattern p2 = Pattern.compile("^\\s*Duration: (\\d\\d):(\\d\\d):(\\d\\d)\\.(\\d\\d).*$", 2);Pattern p3 = Pattern.compile("^\\s*Stream #\\S+: ((?:Audio)|(?:Video)|(?:Data)): (.*)\\s*$", 2);Pattern p4 = Pattern.compile("^\\s*Metadata:", 2);MultimediaInfo info = null;try {int step = 0;while(true) {String line = reader.readLine();LOG.debug("Output line: " + line);if (line == null) {break;}Matcher m;String type;switch(step) {case 0:String token = source.getAbsolutePath() + ": ";if (line.startsWith(token)) {String message = line.substring(token.length());throw new InputFormatException(message);}Matcher m = p1.matcher(line);if (m.matches()) {type = m.group(1);info = new MultimediaInfo();info.setFormat(type);++step;}break;case 1:m = p2.matcher(line);if (m.matches()) {long hours = (long)Integer.parseInt(m.group(1));long minutes = (long)Integer.parseInt(m.group(2));long seconds = (long)Integer.parseInt(m.group(3));long dec = (long)Integer.parseInt(m.group(4));long duration = dec * 10L + seconds * 1000L + minutes * 60L * 1000L + hours * 60L * 60L * 1000L;info.setDuration(duration);++step;}break;case 2:m = p3.matcher(line);p4.matcher(line);if (m.matches()) {type = m.group(1);String specs = m.group(2);StringTokenizer st;int i;String token;boolean parsed;Matcher m2;int bitRate;if ("Video".equalsIgnoreCase(type)) {VideoInfo video = new VideoInfo();st = new StringTokenizer(specs, ",");for(i = 0; st.hasMoreTokens(); ++i) {token = st.nextToken().trim();if (i == 0) {video.setDecoder(token);} else {parsed = false;m2 = SIZE_PATTERN.matcher(token);if (!parsed && m2.find()) {bitRate = Integer.parseInt(m2.group(1));int height = Integer.parseInt(m2.group(2));video.setSize(new VideoSize(bitRate, height));parsed = true;}m2 = FRAME_RATE_PATTERN.matcher(token);if (!parsed && m2.find()) {try {float frameRate = Float.parseFloat(m2.group(1));video.setFrameRate(frameRate);} catch (NumberFormatException var22) {LOG.info("Invalid frame rate value: " + m2.group(1), var22);}parsed = true;}m2 = BIT_RATE_PATTERN.matcher(token);if (!parsed && m2.find()) {bitRate = Integer.parseInt(m2.group(1));video.setBitRate(bitRate * 1000);parsed = true;}}}info.setVideo(video);} else if ("Audio".equalsIgnoreCase(type)) {AudioInfo audio = new AudioInfo();st = new StringTokenizer(specs, ",");for(i = 0; st.hasMoreTokens(); ++i) {token = st.nextToken().trim();if (i == 0) {audio.setDecoder(token);} else {parsed = false;m2 = SAMPLING_RATE_PATTERN.matcher(token);if (!parsed && m2.find()) {bitRate = Integer.parseInt(m2.group(1));audio.setSamplingRate(bitRate);parsed = true;}m2 = CHANNELS_PATTERN.matcher(token);if (!parsed && m2.find()) {String ms = m2.group(1);if ("mono".equalsIgnoreCase(ms)) {audio.setChannels(1);} else if ("stereo".equalsIgnoreCase(ms)) {audio.setChannels(2);} else if ("quad".equalsIgnoreCase(ms)) {audio.setChannels(4);}parsed = true;}m2 = BIT_RATE_PATTERN.matcher(token);if (!parsed && m2.find()) {bitRate = Integer.parseInt(m2.group(1));audio.setBitRate(bitRate * 1000);parsed = true;}}}info.setAudio(audio);}}}if (line.startsWith("frame=")) {reader.reinsertLine(line);break;}}} catch (IOException var23) {throw new EncoderException(var23);}if (info == null) {throw new InputFormatException();} else {return info;}}
}

3、打包把类打成class文件放到本地的Maven仓库(如果在测试类中使用跳过此步)

 4、测试

String url="https://xxx.mp4";File mediaFile = new File(url);FFmpegFileInfo ffmpegFileInfo = new FFmpegFileInfo(mediaFile);MultimediaInfo info = null;try {info = ffmpegFileInfo.getInfo(url);long duration = info.getDuration();System.out.println("============="+duration/1000);} catch (EncoderException e) {e.printStackTrace();}

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

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

相关文章

性能测试工具 jmeter 录制脚本,传递 cookie,循环执行接口

目录 前言&#xff1a; 代理录制脚本 循环重复添加接口 登录并传递 cookie 给新建产品接口 循环执行脚本 前言&#xff1a; 在使用JMeter进行性能测试时&#xff0c;录制脚本是一种常用的方法。录制脚本可以帮助你捕获和重放用户与应用程序之间的交互&#xff0c;以模拟真…

【线程概念和线程控制】

目录 1 :peach:线程概念 :peach:1.1 :apple:什么是线程&#xff1f;:apple:1.2 :apple:线程的优点和缺点:apple:1.3 :apple:页表的大小:apple:1.4 :apple:线程异常和用途:apple:1.5 :apple:进程VS线程:apple: 2 :peach:线程控制:peach:2.1 :apple:POSIX线程库:apple:2.2 :apple…

D. Rating System

Problem - D - Codeforces 思路&#xff1a;我们先将输入数据做一个前缀和&#xff0c;能够得到它的变化&#xff0c;然后我们能够发现我们只需要找到两个点&#xff0c;第一个点-第二个点最大即可&#xff0c;因为假如说我们现在到了一峰 // Problem: D. Rating System // Con…

计算机网络概述(一)

因特网概述 网络&#xff0c;互联网与因特网的区别联系&#xff1a; 以上是使用有线和无线链路连接的两个网络。那么&#xff0c;要让这两个网络连接起来&#xff0c;就需要路由器。若干个网络通过多个路由器互联起来&#xff0c;就称为了互联网。 因特网是当今世界上最大的互…

Centos安装指定docker版本和docker-compose

目录 一. 直接安装Docker最新镜像源 1. 卸载旧版本的Docker&#xff1a; 2. 安装依赖包&#xff1a; 3. 添加Docker源&#xff1a; 4. 安装Docker&#xff1a; 5. 启动Docker服务&#xff1a; 6. 验证Docker是否安装成功&#xff1a; 二、指定Docker版本安装 1. 查看…

mac电脑 flv转mp4怎么转

mac电脑 flv转mp4怎么转&#xff1f;相信大家平时在电脑上下载视频的时候遇到过这样一个尴尬的事情&#xff0c;下载下来的视频不能被直接打开播放&#xff0c;而是需要使用专门的播放器才能打开查看&#xff0c;例如flv就是这样一种视频格式。大家都知道视频文件的格式种类非常…

Java版spring cloud 本工程项目管理系统源码-全面的工程项目管理

​ ​工程项目管理系统是指从事工程项目管理的企业&#xff08;以下简称工程项目管理企业&#xff09;受业主委托&#xff0c;按照合同约定&#xff0c;代表业主对工程项目的组织实施进行全过程或若干阶段的管理和服务。 如今建筑行业竞争激烈&#xff0c;内卷严重&#xff0c…

计算机中CPU、内存、缓存的关系

CPU&#xff08;Central Processing Unit&#xff0c;中央处理器&#xff09; 内存&#xff08;Random Access Memory&#xff0c;随机存取存储器&#xff09; 缓存&#xff08;Cache&#xff09; CPU、内存和缓存之间有着密切的关系&#xff0c;它们共同构成了计算机系统的核…

【Unity编辑器扩展】编辑器代码一键添加按钮响应事件

此功能能是基于UI变量代码生成工具的改良扩展&#xff1a;【Unity编辑器扩展】UI变量代码自动生成工具(编辑器扩展干货/大幅提高效率)_ui代码自动生成_TopGames的博客-CSDN博客 工具效果预览&#xff1a; UGUI的Button按钮在编辑面板添加响应事件非常繁琐&#xff0c;需要拖个…

微服务:Springboot集成Hystrix实现熔断、降级、隔离

文章目录 前言知识积累Springboot集成Hystrix1、maven依赖引入2、application开启feign的hystrix支持&#xff08;客户端配置限流降级熔断&#xff09;3、入口类增加EnableFeignClients EnableHystrix 开启feign与hystrix4、feign调用增加降级方法服务端配置限流降级熔断(选择使…

JavaWeb——基于Spring Boot的图书数字化管理系统的设计与实现

课程设计总结 1 概述 1.1 项目开发背景 随着信息技术的快速发展&#xff0c;数字化管理已经成为各行各业提高效率和管理水平的重要手段。在图书管理领域&#xff0c;数字化管理系统可以有效地提高管理效率&#xff0c;提供更好的用户体验。本项目旨在开发一个基于Spring…

Vue使用keep-alive设置哪些组件可以被缓存,哪些不被缓存

需求&#xff1a;当一个项目中&#xff0c;不是所有的组件页面都需要缓存起来&#xff0c;因为有些页面是不需要的 <keep-alive><router-view v-if"$route.meta.keepAlive"></router-view> </keep-alive><router-view v-if"!$rout…

关于Context和ContextImpl还有ContextWrapper的关系

关于Context和ContextImpl还有ContextWrapper的关系 1.Context和ContextImpl还有ContextWrapper的关系 ​ 图一.Context和ContextImpl还有ContextWrapper的关系示意图 1.1.ContextImpl是Context的实现类 从Context和ContextImpl的源代码中,可以看出Context是一个抽象类,具体…

机器学习概括

文章目录 一、机器学习是什么&#xff1f;二、模型训练YouTube流量预测1. 先写一个具有未知参数的函数&#xff08;Function&#xff09;2. 定义损失&#xff08;从训练数据进行计算&#xff09;3.最优化4.结果分析 Back to framework1.带有未知数的函数&#xff1a;2.定义损失…

K8S应用流程安全(镜像安全 配置管理 访问安全)

应用流程安全 1 应用流程安全1.1 镜像安全1.1.1 构建原则1.1.2 Dockerfile实践1.1.3 构建进阶1.1.4 镜像检测1.1.5 仓库升级1.1.6 高可用仓库1.1.7 镜像策略 1.2 配置管理1.2.1 配置基础1.2.2 YAML安全1.2.3 kustomize1.2.4 基础实践1.2.5 功能复用1.2.6 配置定制1.2.7 补丁实践…

当你按下键盘A键

CPU 里面的内存接口&#xff0c;直接和系统总线通信&#xff0c;然后系统总线再接入一个 I/O 桥接器&#xff0c;这个 I/O 桥接器&#xff0c;另一边接入了内存总线&#xff0c;使得 CPU 和内存通信。再另一边&#xff0c;又接入了一个 I/O 总线&#xff0c;用来连接 I/O 设备&…

el-table 动态合并不定项多级表头

我们的需求是根据不同的厂配不同的多级表头,每个表头有需要合并的项,并且不确定 如图所示 对表格进行循环操作,此处不赘述,最下方有全部代码 表头是单独写在js方便后期更改,然后引入js文件,然后根据情况去调取 // 获取表头getHeader(nv) {this.factoryCodes nv;this.heade…

【UE4 C++】根据指定路径生成静态网格体

在上一篇博客中&#xff08;【UE C】蓝图调用C函数&#xff09;&#xff0c;我们用C创建了一个蓝图函数库&#xff0c;本篇文章在这个蓝图函数库基础上增加一个方法&#xff0c;该方法只需输入一个文件目录路径&#xff0c;就可在场景中生成该目录下得所有静态网格体。&#xf…

第6集丨JavaScript 使用原型(prototype)实现继承——最佳实战3

目录 一、原型继承与属性拷贝1.1 功能说明1.2 功能测试 二、多重继承2.1 功能实现2.2 功能测试 三、寄生式继承四、构造器借用4.1 简单实现4.2 进化版4.2.1 功能实现4.2.2 案例测试 五、借用构造器和原型复制六 综合案例6.1 需求说明6.2 代码实现 一、原型继承与属性拷贝 1.1 功…

css之:is()、:where()和:has()伪元素的运用、使用、important

文章目录 简介1、:is()2、:where()3、:has() 简介 :is()、:where()和:has()伪元素是CSS中用于样式化元素的非常强大的工具。它们是在CSS选择器Level4规范中引入的。它们允许我们将样式应用于符合特定条件的任何元素&#xff0c;例如元素的类型、元素的位置和元素的后代。 1、:i…