From dd299c7a228cd37b896857ed6a094dbbb62e6fd9 Mon Sep 17 00:00:00 2001
From: Dana <Dana_Lee1016@126.com>
Date: 星期二, 23 十二月 2025 14:51:43 +0800
Subject: [PATCH] 1.在文件传输前引入 resolvedFilePath,若原路径不存在,则从文件名解析时间戳,生成日期目录 yyyyMMdd,到 TF 卡路径 /h264/<日期>/ 下查找同名文件,找到后使用其绝对路径传输。 失败场景均记录日志并返回 1;成功找到会记录 TF 卡命中。 传输与日志都改用 resolvedFilePath。
---
app/src/main/java/com/anyun/h264/H264EncodeService.java | 194 ++++++++++++++++++++++++++++++++++++++++++------
1 files changed, 170 insertions(+), 24 deletions(-)
diff --git a/app/src/main/java/com/anyun/h264/H264EncodeService.java b/app/src/main/java/com/anyun/h264/H264EncodeService.java
index f65b77e..af647b2 100644
--- a/app/src/main/java/com/anyun/h264/H264EncodeService.java
+++ b/app/src/main/java/com/anyun/h264/H264EncodeService.java
@@ -20,6 +20,7 @@
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
+import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
@@ -37,6 +38,7 @@
private H264FileTransmitter h264FileTransmitter; // H264鏂囦欢浼犺緭鍣�
private String outputFileDirectory; // H264鏂囦欢杈撳嚭鐩綍
private WatermarkInfo currentWatermarkInfo; // 褰撳墠姘村嵃淇℃伅
+ private boolean currentUseTFCard = true; // 褰撳墠鏄惁浣跨敤TF鍗¢厤缃�
private static final int H264_FILE_RETENTION_DAYS = 1; // 鍙牴鎹渶姹傝皟鏁翠负3鎴�5澶�
// 澶氳繘绋嬫敮鎸侊細绗簩涓憚鍍忓ご鐨勬湇鍔¤繛鎺�
@@ -500,7 +502,7 @@
Timber.e("Network transmit requires valid ip and port in config");
return 1; // 澶辫触
}
- }
+ }
// 鍒涘缓缂栫爜鍣�
h264Encoder = new H264Encoder();
@@ -511,9 +513,12 @@
// 璁剧疆缂栫爜鍙傛暟锛堜娇鐢ㄩ厤缃腑鐨勫弬鏁帮級
int width = config != null && config.width > 0 ? config.width : DEFAULT_WIDTH;
int height = config != null && config.height > 0 ? config.height : DEFAULT_HEIGHT;
- int framerate = config != null && config.framerate > 0 ? config.framerate : DEFAULT_FRAME_RATE;
+ int framerate = config != null && config.framerate > 0 ? config.framerate : DEFAULT_FRAME_RATE;
h264Encoder.setEncoderParams(width, height, framerate, DEFAULT_BITRATE);
+ // 淇濆瓨褰撳墠useTFCard閰嶇疆
+// currentUseTFCard = config.useTFCard;
+
// 鑾峰彇杈撳嚭鏂囦欢鐩綍锛堟牴鎹畊seTFCard閰嶇疆锛�
String outputDir = getOutputFileDirectory(config.useTFCard);
@@ -612,11 +617,48 @@
}
try {
- // 妫�鏌ユ枃浠舵槸鍚﹀瓨鍦�
- File file = new File(config.filePath);
+ // 瑙f瀽寰呬紶杈撴枃浠惰矾寰勶紝鑻ヤ笉瀛樺湪鍒欏皾璇曞埌TF鍗$洰褰曟寜鏃ユ湡鏌ユ壘
+ String resolvedFilePath = config.filePath;
+ File file = new File(resolvedFilePath);
if (!file.exists() || !file.isFile()) {
- Timber.e("File does not exist: %s", config.filePath);
- return 1; // 澶辫触
+ Timber.w("File does not exist, try TF card lookup: %s", resolvedFilePath);
+
+ String fileName = file.getName();
+ String timestampStr = null;
+ if (fileName.startsWith("h264_") && fileName.endsWith(".h264")) {
+ timestampStr = fileName.substring(5, fileName.length() - 5);
+ }
+
+ if (timestampStr == null || timestampStr.trim().isEmpty()) {
+ Timber.e("Cannot parse timestamp from file name: %s", fileName);
+ return 1; // 澶辫触
+ }
+
+ try {
+ long timestamp = Long.parseLong(timestampStr);
+ SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd", Locale.CHINA);
+ String dateDir = dateFormat.format(new Date(timestamp));
+
+ String storagePath = FileUtil.getStoragePath(this, true);
+ if (storagePath == null || storagePath.trim().isEmpty()) {
+ Timber.e("TF card storage path not available when searching file");
+ return 1; // 澶辫触
+ }
+
+ File tfRoot = new File(storagePath, "h264");
+ File candidate = new File(new File(tfRoot, dateDir), fileName);
+ if (candidate.exists() && candidate.isFile()) {
+ resolvedFilePath = candidate.getAbsolutePath();
+ file = candidate;
+ Timber.i("Found file on TF card: %s", resolvedFilePath);
+ } else {
+ Timber.e("File not found on TF card path: %s", candidate.getAbsolutePath());
+ return 1; // 澶辫触
+ }
+ } catch (NumberFormatException e) {
+ Timber.e(e, "Failed to parse timestamp from file name: %s", fileName);
+ return 1; // 澶辫触
+ }
}
// 鍒涘缓鏂囦欢浼犺緭鍣�
@@ -665,10 +707,10 @@
}
// 寮�濮嬩紶杈撴枃浠�
- h264FileTransmitter.transmitFile(config.filePath);
+ h264FileTransmitter.transmitFile(resolvedFilePath);
Timber.d("File transmit started successfully, file: %s, server: %s:%d, protocol: %s, framerate: %d",
- config.filePath, config.ip, config.port,
+ resolvedFilePath, config.ip, config.port,
config.protocolType == JT1076ProtocolHelper.PROTOCOL_TYPE_UDP ? "UDP" : "TCP", framerate);
return 0; // 鎴愬姛
@@ -716,30 +758,90 @@
* @return 璧勬簮鍒楄〃
*/
private List<ResourceInfo> getResourceList(String startTime, String endTime) {
- Timber.d("getResourceList called, startTime: %s, endTime: %s", startTime, endTime);
+ Timber.d("getResourceList called, startTime: %s, endTime: %s, useTFCard: %b", startTime, endTime, currentUseTFCard);
List<ResourceInfo> resourceList = new ArrayList<>();
try {
- // 鎵弿杈撳嚭鐩綍涓殑H264鏂囦欢
- File dir = new File(outputFileDirectory);
- if (!dir.exists() || !dir.isDirectory()) {
- Timber.w("Output directory does not exist: %s", outputFileDirectory);
- return resourceList;
- }
-
- File[] files = dir.listFiles((dir1, name) -> name.toLowerCase().endsWith(".h264"));
- if (files == null || files.length == 0) {
- Timber.d("No H264 files found in directory");
- return resourceList;
- }
-
// 瑙f瀽鏃堕棿鑼冨洿
Date startDate = parseTime(startTime);
Date endDate = parseTime(endTime);
if (startDate == null || endDate == null) {
Timber.e("Invalid time format, startTime: %s, endTime: %s", startTime, endTime);
+ return resourceList;
+ }
+
+ if (currentUseTFCard) {
+ // 浣跨敤TF鍗★細鎵弿TF鍗′笂鐨刪264鏂囦欢澶癸紝鏍规嵁鏃ユ湡鑼冨洿杩囨护
+ String storagePath = FileUtil.getStoragePath(this, true);
+ if (storagePath == null || storagePath.trim().isEmpty()) {
+ Timber.w("TF card storage path not available, fallback to app directory");
+ // 鍥為��鍒板簲鐢ㄧ洰褰�
+ return getResourceListFromDirectory(outputFileDirectory, startDate, endDate);
+ }
+
+ File externalStorage = new File(storagePath);
+ if (!externalStorage.exists()) {
+ Timber.w("TF card storage directory does not exist: %s, fallback to app directory", storagePath);
+ // 鍥為��鍒板簲鐢ㄧ洰褰�
+ return getResourceListFromDirectory(outputFileDirectory, startDate, endDate);
+ }
+
+ // TF鍗′笂鐨刪264鏂囦欢澶硅矾寰勶細/sdcard/h264/
+ File h264Dir = new File(externalStorage, "h264");
+ if (!h264Dir.exists() || !h264Dir.isDirectory()) {
+ Timber.w("TF card h264 directory does not exist: %s", h264Dir.getAbsolutePath());
+ return resourceList;
+ }
+
+ // 鑾峰彇鏃ユ湡鑼冨洿鍐呯殑鎵�鏈夋棩鏈熸枃浠跺す
+ List<String> dateDirs = getDateDirectoriesInRange(startDate, endDate);
+ Timber.d("Found %d date directories in range", dateDirs.size());
+
+ // 鎵弿姣忎釜鏃ユ湡鏂囦欢澶逛笅鐨刪264鏂囦欢
+ for (String dateDir : dateDirs) {
+ File dateDirFile = new File(h264Dir, dateDir);
+ if (dateDirFile.exists() && dateDirFile.isDirectory()) {
+ List<ResourceInfo> dateResources = getResourceListFromDirectory(
+ dateDirFile.getAbsolutePath(), startDate, endDate);
+ resourceList.addAll(dateResources);
+ }
+ }
+
+ Timber.d("Found %d resources in TF card time range", resourceList.size());
+ return resourceList;
+ } else {
+ // 涓嶄娇鐢═F鍗★細鎵弿搴旂敤鐩綍
+ return getResourceListFromDirectory(outputFileDirectory, startDate, endDate);
+ }
+
+ } catch (Exception e) {
+ Timber.e(e, "Error getting resource list");
+ return resourceList;
+ }
+ }
+
+ /**
+ * 浠庢寚瀹氱洰褰曟壂鎻廐264鏂囦欢骞跺垱寤鸿祫婧愬垪琛�
+ * @param directoryPath 鐩綍璺緞
+ * @param startDate 寮�濮嬫棩鏈�
+ * @param endDate 缁撴潫鏃ユ湡
+ * @return 璧勬簮鍒楄〃
+ */
+ private List<ResourceInfo> getResourceListFromDirectory(String directoryPath, Date startDate, Date endDate) {
+ List<ResourceInfo> resourceList = new ArrayList<>();
+
+ try {
+ File dir = new File(directoryPath);
+ if (!dir.exists() || !dir.isDirectory()) {
+ Timber.w("Directory does not exist: %s", directoryPath);
+ return resourceList;
+ }
+
+ File[] files = dir.listFiles((dir1, name) -> name.toLowerCase().endsWith(".h264"));
+ if (files == null || files.length == 0) {
+ Timber.d("No H264 files found in directory: %s", directoryPath);
return resourceList;
}
@@ -751,16 +853,60 @@
}
}
- Timber.d("Found %d resources in time range", resourceList.size());
return resourceList;
} catch (Exception e) {
- Timber.e(e, "Error getting resource list");
+ Timber.e(e, "Error getting resource list from directory: %s", directoryPath);
return resourceList;
}
}
/**
+ * 鑾峰彇鏃ユ湡鑼冨洿鍐呯殑鎵�鏈夋棩鏈熸枃浠跺す鍚嶇О鍒楄〃锛堟牸寮忥細yyyyMMdd锛�
+ * @param startDate 寮�濮嬫棩鏈�
+ * @param endDate 缁撴潫鏃ユ湡
+ * @return 鏃ユ湡鏂囦欢澶瑰悕绉板垪琛�
+ */
+ private List<String> getDateDirectoriesInRange(Date startDate, Date endDate) {
+ List<String> dateDirs = new ArrayList<>();
+
+ try {
+ SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd", Locale.CHINA);
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTime(startDate);
+ calendar.set(Calendar.HOUR_OF_DAY, 0);
+ calendar.set(Calendar.MINUTE, 0);
+ calendar.set(Calendar.SECOND, 0);
+ calendar.set(Calendar.MILLISECOND, 0);
+
+ Date currentDate = calendar.getTime();
+ Date endDateOnly = new Date(endDate.getTime());
+ Calendar endCalendar = Calendar.getInstance();
+ endCalendar.setTime(endDateOnly);
+ endCalendar.set(Calendar.HOUR_OF_DAY, 23);
+ endCalendar.set(Calendar.MINUTE, 59);
+ endCalendar.set(Calendar.SECOND, 59);
+ endCalendar.set(Calendar.MILLISECOND, 999);
+ endDateOnly = endCalendar.getTime();
+
+ // 閬嶅巻浠庡紑濮嬫棩鏈熷埌缁撴潫鏃ユ湡鐨勬墍鏈夋棩鏈�
+ while (!currentDate.after(endDateOnly)) {
+ String dateDir = dateFormat.format(currentDate);
+ dateDirs.add(dateDir);
+
+ // 澧炲姞涓�澶�
+ calendar.add(Calendar.DAY_OF_MONTH, 1);
+ currentDate = calendar.getTime();
+ }
+
+ } catch (Exception e) {
+ Timber.e(e, "Error getting date directories in range");
+ }
+
+ return dateDirs;
+ }
+
+ /**
* 璁剧疆姘村嵃淇℃伅
* @param watermarkInfoJson 姘村嵃淇℃伅JSON瀛楃涓诧紝鍖呭惈锛氳溅鐗�(plateNumber)銆佸鍛�(student)銆佹暀缁�(coach)銆�
* 缁忓害(longitude)銆佺含搴�(latitude)銆侀┚鏍�(drivingSchool)銆佽溅閫�(speed)
--
Gitblit v1.8.0