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

news2024/11/22 11:00:19

 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.coloradmin.cn/o/754920.html

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

相关文章

KEIL安装额外版本的arm compiler v6.16 v5.06update7

很多时候安装了一个版本的keil&#xff0c;但是别人的工程是拿另一个版本做的&#xff0c;重新安装也不是不行&#xff0c;但是会占很多地方&#xff0c;文件关联也很乱套&#xff0c;所以记录一下怎么安装额外的&#xff0c;比如我的是keil mdk530&#xff0c;自带Compiler v6…

Linux 离线安装软件

这里写目录标题 0.注意1.防火墙操作2.安装jdk1.上传jdk安装包2.安装3.配置环境变量 3.安装redis1.上传tar包2.安装命令3.项目连接时报错4.问题一保存信息解决 4.安装rabbitMq1.查看erlang与mq对应版本2.下载软件2.1下载erlang2.2下载rabbitMq 3.将文件拖放到linux4.安装5.开放端…

loki技巧 - 结构化log日志文本

将非结构化的log日志信息结构化为JSON格式&#xff0c;以方便在Grafana界面侧的浏览和查询。 0. 目录 1. 需求背景和描述2. 实现&#xff08;Promtail侧&#xff09;3. 注意事项4. 参考 1. 需求背景和描述 最近几个月&#xff0c;部门内部开始尝试统一日志收集、查询统计相关的…

没有广告的浏览器(AdBlock)

AdBlock是一个广告拦截器&#xff0c;可以帮你拦截所有浏览网站上的广告。 安装&#xff1a; 有梯子 1、官网 https://getadblock.com/zh_CN/ 2、点击【以及获得Adblock】跳转浏览器->扩展程序->插件详情页&#xff0c;目前支持 Chrome Firefox Edge Safari 浏览器&am…

KaiwuDB CTO 魏可伟:多模架构 —“化繁为简”加速器

以下为浪潮 KaiwuDB CTO 魏可伟受邀于7月4日在京举行的可信数据库发展大会发表演讲的实录&#xff0c;欢迎大家点赞、收藏、关注&#xff01; 打造多模引擎&#xff0c;AIoT数据库探索之路 01 何为“繁”&#xff1f; 工业 4.0 时代&#xff0c; 物联网产业驱动数据要素市场不…

H3C-Cloud Lab实验-PPP实验

实验拓扑图&#xff1a; 实验需求&#xff1a; 1. R1 和 R2 使用 PPP 链路直连&#xff0c;R2 和 R3 把 2 条 PPP 链路捆绑为 PPP MP 直连 2. 按照图示配置 IP 地址 3. R2 对 R1 的 PPP 进行单向 chap 验证 4. R2 和 R3 的 PPP 进行双向 chap 验证 实验步骤&#xff1a; …

SkipList

文章目录 SkipList理解跳表从单链表说起查找的时间复杂度空间复杂度插入数据更高效的方式维护索引代码实现索引的抽取概率算法 举例插入元素 删除数据总结为什么Redis选择使用跳表而不是红黑树来实现有序集合 SkipList 理解跳表从单链表说起 在原始单链表中查找元素&#xff…

C# Linq 详解三

目录 概述 十三、Sum / Min / Max / Average 十四、Distinct 十五、Concat 十六、Join 十七、ToList 十八、ToArray 十九、ToDictionary C# Linq 详解一 1.Where 2.Select 3.GroupBy 4.First / FirstOrDefault 5.Last / LastOrDefault C# Linq 详解二 1.OrderBy 2.O…

HOT64-搜索二维矩阵

leetcode原题链接&#xff1a;搜索二维矩阵 题目描述 给你一个满足下述两条属性的 m x n 整数矩阵&#xff1a; 每行中的整数从左到右按非递减顺序排列。每行的第一个整数大于前一行的最后一个整数。 给你一个整数 target &#xff0c;如果 target 在矩阵中&#xff0c;返回…

Leetcode每日一题:979. 在二叉树中分配硬币(2023.7.14 C++)

目录 979. 在二叉树中分配硬币 题目描述&#xff1a; 实现代码与解析&#xff1a; dfs&#xff08;后序遍历&#xff09; 原理思路&#xff1a; 979. 在二叉树中分配硬币 题目描述&#xff1a; 给定一个有 N 个结点的二叉树的根结点 root&#xff0c;树中的每个结点上都对…

宋浩高等数学笔记(一)函数与极限

b站宋浩老师的高等数学网课&#xff0c;全套笔记已记完&#xff0c;不定期复习并发布更新。 章节顺序与同济大学第七版教材所一致。

C++虚函数学习

VC6新建一个单文档工程&#xff1b; 添加一个一般类&#xff1b; 生成的Shape.cpp保持不变&#xff1b; #include "Shape.h"#ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]__FILE__; #define new DEBUG_NEW #endif// // Construction/Destruction //Shap…

Unity平台如何实现RTSP转RTMP推送?

技术背景 Unity平台下&#xff0c;RTSP、RTMP播放和RTMP推送&#xff0c;甚至包括轻量级RTSP服务这块都不再赘述&#xff0c;今天探讨的一位开发者提到的问题&#xff0c;如果在Unity下&#xff0c;实现RTSP播放的同时&#xff0c;随时转RTMP推送出去&#xff1f; RTSP转RTMP…

使用Google Chrome浏览器打开Vue项目报错“Uncaught runtime errors”——已解决

使用Google Chrome浏览器打开Vue项目报错&#xff1a; Uncaught runtime errors:ERROR Identifier originalPrompt has already been declared SyntaxError: Identifier originalPrompt has already been declared问题原因&#xff1a; Google Chrome浏览器安装了插件跟Vue项…

2023年最新水果编曲软件FLStudio21.0.3.3517中文直装完整至尊解版下载

2023年最新水果编曲软件FLStudio21.0.3.3517中文直装完整至尊解版下载 是最好的音乐开发和制作软件也称为水果循环。它是最受欢迎的工作室&#xff0c;因为它包含了一个主要的听觉工作场所。 最新fl studio 21有不同的功能&#xff0c;如它包含图形和音乐音序器&#xff0c;帮助…

Nginx Linux设置开机自启动

使用如下命令 vi /lib/systemd/system/nginx.service 创建并编辑文件将以下代码黏贴至此文件中 [Unit] Descriptionnginx Afternetwork.target[Service] Typeforking TimeoutSec0 #防止启动超时 Userroot Grouproot criptionnacos Afternetwork.target[Service] Typeforking T…

哈希的应用(1)——位图

计算机存储单位的常用知识 2^30大约等于10亿 1byte8bit--一个字节等于八个比特位 左移操作符<<表示将值从底地址到高地址的方向移动。 bitset<-1>&#xff0c;开了2^32个bit512MB1GB 位图概念 面试题 给40亿个不重复的无符号整数&#xff0c;没排过序。给一个无符…

Kerberos协议详解

0x01 kerberos协议的角色组成 Kerberos协议中存在三个角色&#xff1a; 客户端(Client)&#xff1a;发送请求的一方 服务端(Server)&#xff1a;接收请求的一方 密钥分发中心(Key distribution KDC) 密钥分发中心分为两个部分&#xff1a; AS(Authentication Server)&…

Linux下JDK版本与安装版本不一致问题

目录 一. &#x1f981; 前言二. &#x1f981; 操作流程三. &#x1f981; 总结四. &#x1f981; Happy Ending 一. &#x1f981; 前言 最近重新安装了centos7.9,针对以前遇到的Java版本不一致的情况, 提出了另一种方法,该方法简单易行,容易理解。 二. &#x1f981; 操作…

吴恩达机器学习2022-Jupyter1可选实验室: Python 和 Jupyter 笔记本简介

欢迎来到第一个可选实验室&#xff01; 可供选择的实验室包括:提供信息-比如这个笔记本以实际例子加强课堂教材提供分级实验室常规的工作实例 1.1 目标 在本实验中&#xff0c;您将: 对Jupyter笔记本进行简要介绍&#xff0c;参观Jupyter笔记本&#xff0c;了解标记单元格和…