package org.sxkj.common.utils;
|
|
import org.sxkj.common.model.SubtitleFrame;
|
|
import java.io.IOException;
|
import java.nio.file.Files;
|
import java.nio.file.Paths;
|
import java.time.LocalDateTime;
|
import java.time.LocalTime;
|
import java.time.format.DateTimeFormatter;
|
import java.util.ArrayList;
|
import java.util.HashMap;
|
import java.util.List;
|
import java.util.Map;
|
import java.util.regex.Matcher;
|
import java.util.regex.Pattern;
|
|
/**
|
* srt 文件解析工具类
|
*/
|
public class SrtParserUtils {
|
|
private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm:ss,SSS");
|
private static final DateTimeFormatter TIMESTAMP_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
|
|
/**
|
* srt 文件解析
|
* @param filePath
|
* @return
|
* @throws IOException
|
*/
|
public static List<SubtitleFrame> parseSrtFile(String filePath) throws IOException {
|
List<SubtitleFrame> frames = new ArrayList<>();
|
String content = new String(Files.readAllBytes(Paths.get(filePath)));
|
String[] blocks = content.split("\\n\\n+");
|
|
for (String block : blocks) {
|
if (block.trim().isEmpty()) {
|
continue;
|
}
|
|
String[] lines = block.split("\\n");
|
if (lines.length < 3) {
|
continue;
|
}
|
|
try {
|
int index = Integer.parseInt(lines[0].trim());
|
String[] timeRange = lines[1].trim().split(" --> ");
|
String startTime = timeRange[0].trim();
|
String endTime = timeRange[1].trim();
|
|
StringBuilder contentBuilder = new StringBuilder();
|
for (int i = 2; i < lines.length; i++) {
|
contentBuilder.append(lines[i].trim()).append(" ");
|
}
|
String contentText = contentBuilder.toString().trim();
|
|
// 解析帧计数和时间戳
|
Pattern framePattern = Pattern.compile("FrameCnt:\\s*(\\d+)\\s+(\\d{4}-\\d{2}-\\d{2}\\s+\\d{2}:\\d{2}:\\d{2}\\.\\d{3})");
|
Matcher frameMatcher = framePattern.matcher(contentText);
|
if (!frameMatcher.find()) {
|
continue;
|
}
|
|
int frameCount = Integer.parseInt(frameMatcher.group(1));
|
LocalDateTime timestamp = LocalDateTime.parse(frameMatcher.group(2), TIMESTAMP_FORMATTER);
|
|
// 解析元数据
|
Map<String, String> metadata = parseMetadata(contentText);
|
|
// 构建相机参数
|
Map<String, String> cameraParams = new HashMap<>();
|
cameraParams.put("iso", metadata.get("iso"));
|
cameraParams.put("shutter", metadata.get("shutter"));
|
cameraParams.put("fnum", metadata.get("fnum"));
|
cameraParams.put("ev", metadata.get("ev"));
|
cameraParams.put("color_md", metadata.get("color_md"));
|
cameraParams.put("ae_meter_md", metadata.get("ae_meter_md"));
|
cameraParams.put("focal_len", metadata.get("focal_len"));
|
cameraParams.put("dzoom_ratio", metadata.get("dzoom_ratio"));
|
cameraParams.put("dehaze_level", metadata.get("dehaze_level"));
|
cameraParams.put("dehaze_mode", metadata.get("dehaze_mode"));
|
|
// 构建GPS数据
|
Map<String, Double> gpsData = new HashMap<>();
|
gpsData.put("latitude", Double.parseDouble(metadata.getOrDefault("latitude", "0")));
|
gpsData.put("longitude", Double.parseDouble(metadata.getOrDefault("longitude", "0")));
|
gpsData.put("rel_alt", Double.parseDouble(metadata.getOrDefault("rel_alt", "0")));
|
gpsData.put("abs_alt", Double.parseDouble(metadata.getOrDefault("abs_alt", "0")));
|
|
// 构建方向数据
|
Map<String, Double> orientation = new HashMap<>();
|
orientation.put("yaw", Double.parseDouble(metadata.getOrDefault("gb_yaw", "0")));
|
orientation.put("pitch", Double.parseDouble(metadata.getOrDefault("gb_pitch", "0")));
|
orientation.put("roll", Double.parseDouble(metadata.getOrDefault("gb_roll", "0")));
|
|
// 其他数据
|
Map<String, String> otherData = new HashMap<>();
|
for (Map.Entry<String, String> entry : metadata.entrySet()) {
|
if (!cameraParams.containsKey(entry.getKey()) &&
|
!gpsData.containsKey(entry.getKey()) &&
|
!orientation.containsKey(entry.getKey())) {
|
otherData.put(entry.getKey(), entry.getValue());
|
}
|
}
|
|
SubtitleFrame frame = new SubtitleFrame(
|
index, startTime, endTime, frameCount, timestamp,
|
cameraParams, gpsData, orientation, otherData
|
);
|
|
frames.add(frame);
|
} catch (Exception e) {
|
System.err.println("Error parsing block: " + e.getMessage());
|
continue;
|
}
|
}
|
|
return frames;
|
}
|
|
private static LocalTime parseSrtTime(String timeStr) {
|
// 处理SRT时间格式,如 00:00:00,000
|
timeStr = timeStr.replace(',', '.');
|
return LocalTime.parse(timeStr, TIME_FORMATTER);
|
}
|
|
private static Map<String, String> parseMetadata(String text) {
|
// 先处理特殊字段
|
text = text.replaceAll("\\[rel_alt:\\s*([-\\d.]+)\\s*abs_alt:\\s*([-\\d.]+)\\]",
|
"[rel_alt: $1] [abs_alt: $2]");
|
|
text = text.replaceAll("\\[gb_yaw:\\s*([-\\d.]+)\\s*gb_pitch:\\s*([-\\d.]+)\\s*gb_roll:\\s*([-\\d.]+)\\]",
|
"[gb_yaw: $1] [gb_pitch: $2] [gb_roll: $3]");
|
|
// 解析所有键值对
|
Map<String, String> metadata = new HashMap<>();
|
Pattern pattern = Pattern.compile("\\[([^:]+):\\s*([^\\]]+)\\]");
|
Matcher matcher = pattern.matcher(text);
|
|
while (matcher.find()) {
|
metadata.put(matcher.group(1).trim(), matcher.group(2).trim());
|
}
|
|
return metadata;
|
}
|
|
// public static void main(String[] args) {
|
// try {
|
// String srtPath = "C:\\Users\\Administrator\\Desktop\\temp\\视频\\倾斜视频\\DJI_20250527181054_0002_V\\out.srt";
|
// List<SubtitleFrame> frames = SrtParserUtils.parseSrtFile(srtPath);
|
//
|
// for (SubtitleFrame frame : frames) {
|
// System.out.println("Frame #" + frame.getIndex());
|
// System.out.println("Time: " + frame.getStartTime() + " - " + frame.getEndTime());
|
// System.out.println("Frame count: " + frame.getFrameCount());
|
// System.out.println("Timestamp: " + frame.getTimestamp());
|
// System.out.println("GPS: " + frame.getGpsData());
|
// System.out.println("Orientation: " + frame.getOrientation());
|
// System.out.println("----------------------");
|
// }
|
// } catch (IOException e) {
|
// e.printStackTrace();
|
// }
|
// }
|
}
|