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