package com.ard.sample.utils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.io.BufferedReader; import java.io.InputStreamReader; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * 视频时长解析工具类(FFmpeg 命令行版) * 无需下载文件,直接解析远程 HTTPS 地址的 MP4 视频时长 */ @Component public class VideoDurationUtilFFmpeg { private static final Pattern DURATION_PATTERN = Pattern.compile("Duration: (\\d{2}):(\\d{2}):(\\d{2}\\.\\d{2})"); /** * 获取远程 HTTPS 地址的 MP4 视频时长 * @param videoHttpsUrl 视频 HTTPS 地址 * @return 视频时长(秒,保留2位小数),解析失败返回 null */ public double getRemoteMp4Duration(String videoHttpsUrl) { // 入参校验 if (videoHttpsUrl == null || !videoHttpsUrl.trim().toLowerCase().startsWith("https") || !videoHttpsUrl.trim().toLowerCase().endsWith(".mp4")) { throw new IllegalArgumentException("无效的MP4视频HTTPS地址:" + videoHttpsUrl); } try { // 构建 FFmpeg 命令,直接解析远程 URL String[] command = { "ffmpeg", "-i", videoHttpsUrl, "-hide_banner" }; Process process = new ProcessBuilder(command) .redirectErrorStream(true) .start(); BufferedReader reader = new BufferedReader( new InputStreamReader(process.getInputStream()) ); String line; while ((line = reader.readLine()) != null) { Matcher matcher = DURATION_PATTERN.matcher(line); if (matcher.find()) { int hours = Integer.parseInt(matcher.group(1)); int minutes = Integer.parseInt(matcher.group(2)); double seconds = Double.parseDouble(matcher.group(3)); double totalSeconds = hours * 3600 + minutes * 60 + seconds; return totalSeconds; // return new BigDecimal(totalSeconds) // .setScale(2, RoundingMode.HALF_UP); } } // 等待进程结束 process.waitFor(); if (process.exitValue() != 0) { throw new RuntimeException("FFmpeg 执行失败,退出码:" + process.exitValue()); } } catch (Exception e) { System.err.println("解析视频时长失败,URL:" + videoHttpsUrl + ",异常:" + e.getMessage()); } return -1; } // // 测试方法(可删除) // public static void main(String[] args) { // VideoDurationUtilFFmpeg util = new VideoDurationUtilFFmpeg(); // // TimestampUtils _timestampUtils = new TimestampUtils(); // // 替换为你的测试视频 URL // double duration = util.getRemoteMp4Duration("https://192.168.1.3:9001/dockfile/wayline/d16eb96c-a0cc-458f-852c-09dddd59827f/DJI_202602121540_002_d16eb96c-a0cc-458f-852c-09dddd59827f/DJI_20260212154239_0004_V.mp4"); // long endTime=_timestampUtils.plusSecondsByMillis(System.currentTimeMillis(),duration); // if (duration != -1) { // System.out.println("视频时长:" + duration + " 秒"); // System.out.println("视频结束时间:" + endTime); // } else { // System.out.println("解析失败"); // } // } }