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