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("解析失败");
|
// }
|
// }
|
}
|