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/H264EncodeService2.java | 203 +++++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 180 insertions(+), 23 deletions(-)
diff --git a/app/src/main/java/com/anyun/h264/H264EncodeService2.java b/app/src/main/java/com/anyun/h264/H264EncodeService2.java
index cced8b3..6644037 100644
--- a/app/src/main/java/com/anyun/h264/H264EncodeService2.java
+++ b/app/src/main/java/com/anyun/h264/H264EncodeService2.java
@@ -17,6 +17,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;
@@ -32,6 +33,7 @@
private H264FileTransmitter h264FileTransmitter; // H264鏂囦欢浼犺緭鍣�
private String outputFileDirectory; // H264鏂囦欢杈撳嚭鐩綍
private WatermarkInfo currentWatermarkInfo; // 褰撳墠姘村嵃淇℃伅
+ private boolean currentUseTFCard = false; // 褰撳墠鏄惁浣跨敤TF鍗¢厤缃�
// 榛樿缂栫爜鍙傛暟
private static final int DEFAULT_WIDTH = 640;
@@ -289,6 +291,9 @@
// 璁剧疆 Context锛堢敤浜庢竻鐞� TF 鍗℃枃浠讹級
h264Encoder.setContext(this);
+ // 淇濆瓨褰撳墠useTFCard閰嶇疆
+ currentUseTFCard = config != null && config.useTFCard;
+
// 璁剧疆缂栫爜鍙傛暟锛堜娇鐢ㄩ厤缃腑鐨勫弬鏁帮級
// 璁剧疆缂栫爜鍙傛暟锛堜娇鐢ㄩ厤缃腑鐨勫弬鏁帮級
int width = config != null && config.width > 0 ? config.width : DEFAULT_WIDTH;
@@ -357,6 +362,9 @@
// 璁剧疆 Context锛堢敤浜庢竻鐞� TF 鍗℃枃浠讹級
h264Encoder.setContext(this);
+
+ // 淇濆瓨褰撳墠useTFCard閰嶇疆
+ currentUseTFCard = config != null && config.useTFCard;
// 璁剧疆缂栫爜鍙傛暟锛堜娇鐢ㄩ厤缃腑鐨勫弬鏁帮級
int width = config != null && config.width > 0 ? config.width : DEFAULT_WIDTH;
@@ -456,11 +464,49 @@
}
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 (camera2)", config.filePath);
- return 1; // 澶辫触
+ Timber.w("File does not exist, try TF card lookup (camera2): %s", resolvedFilePath);
+
+ String fileName = file.getName();
+ String timestampStr = null;
+ // camera2鐨勬枃浠跺悕鏍煎紡锛歨264_camera2_1234567890123.h264
+ if (fileName.startsWith("h264_camera2_") && fileName.endsWith(".h264")) {
+ timestampStr = fileName.substring(14, fileName.length() - 5); // 鍘绘帀 "h264_camera2_" 鍜� ".h264"
+ }
+
+ if (timestampStr == null || timestampStr.trim().isEmpty()) {
+ Timber.e("Cannot parse timestamp from file name (camera2): %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 (camera2)");
+ 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 (camera2): %s", resolvedFilePath);
+ } else {
+ Timber.e("File not found on TF card path (camera2): %s", candidate.getAbsolutePath());
+ return 1; // 澶辫触
+ }
+ } catch (NumberFormatException e) {
+ Timber.e(e, "Failed to parse timestamp from file name (camera2): %s", fileName);
+ return 1; // 澶辫触
+ }
}
// 鍒涘缓鏂囦欢浼犺緭鍣�
@@ -509,10 +555,10 @@
}
// 寮�濮嬩紶杈撴枃浠�
- h264FileTransmitter.transmitFile(config.filePath);
+ h264FileTransmitter.transmitFile(resolvedFilePath);
Timber.d("File transmit started successfully (camera2), 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; // 鎴愬姛
@@ -557,31 +603,98 @@
* 鑾峰彇璧勬簮鍒楄〃锛堟牴鎹甁T/T 1076-2016琛�23瀹氫箟锛�
*/
private List<ResourceInfo> getResourceList(String startTime, String endTime) {
- Timber.d("getResourceList called (camera2), startTime: %s, endTime: %s", startTime, endTime);
+ Timber.d("getResourceList called (camera2), startTime: %s, endTime: %s, useTFCard: %b", startTime, endTime, currentUseTFCard);
List<ResourceInfo> resourceList = new ArrayList<>();
try {
- // 鎵弿杈撳嚭鐩綍涓殑H264鏂囦欢锛堝彧鏌ユ壘camera2鐨勬枃浠讹級
- 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") && name.contains("camera2"));
- if (files == null || files.length == 0) {
- Timber.d("No H264 files found for camera2 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, true);
+ }
+
+ 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, true);
+ }
+
+ // 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鏂囦欢锛堝彧鏌ユ壘camera2鐨勬枃浠讹級
+ for (String dateDir : dateDirs) {
+ File dateDirFile = new File(h264Dir, dateDir);
+ if (dateDirFile.exists() && dateDirFile.isDirectory()) {
+ List<ResourceInfo> dateResources = getResourceListFromDirectory(
+ dateDirFile.getAbsolutePath(), startDate, endDate, true);
+ resourceList.addAll(dateResources);
+ }
+ }
+
+ Timber.d("Found %d resources for camera2 in TF card time range", resourceList.size());
+ return resourceList;
+ } else {
+ // 涓嶄娇鐢═F鍗★細鎵弿搴旂敤鐩綍锛堝彧鏌ユ壘camera2鐨勬枃浠讹級
+ return getResourceListFromDirectory(outputFileDirectory, startDate, endDate, true);
+ }
+
+ } catch (Exception e) {
+ Timber.e(e, "Error getting resource list (camera2)");
+ return resourceList;
+ }
+ }
+
+ /**
+ * 浠庢寚瀹氱洰褰曟壂鎻廐264鏂囦欢骞跺垱寤鸿祫婧愬垪琛�
+ * @param directoryPath 鐩綍璺緞
+ * @param startDate 寮�濮嬫棩鏈�
+ * @param endDate 缁撴潫鏃ユ湡
+ * @param camera2Only 鏄惁鍙煡鎵綾amera2鐨勬枃浠�
+ * @return 璧勬簮鍒楄〃
+ */
+ private List<ResourceInfo> getResourceListFromDirectory(String directoryPath, Date startDate, Date endDate, boolean camera2Only) {
+ 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) -> {
+ boolean isH264 = name.toLowerCase().endsWith(".h264");
+ if (camera2Only) {
+ return isH264 && name.contains("camera2");
+ } else {
+ return isH264;
+ }
+ });
+ if (files == null || files.length == 0) {
+ Timber.d("No H264 files found in directory: %s", directoryPath);
return resourceList;
}
@@ -593,16 +706,60 @@
}
}
- Timber.d("Found %d resources for camera2 in time range", resourceList.size());
return resourceList;
} catch (Exception e) {
- Timber.e(e, "Error getting resource list (camera2)");
+ 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;
+ }
+
+ /**
* 璁剧疆姘村嵃淇℃伅
*/
private void setWatermarkInfo(String watermarkInfoJson) {
--
Gitblit v1.8.0