From 87d885019c9df22ade809b6a2da06545bff9bf98 Mon Sep 17 00:00:00 2001
From: Dana <Dana_Lee1016@126.com>
Date: 星期五, 30 一月 2026 16:26:04 +0800
Subject: [PATCH] 在 startFileRotationTimer() 的定时回调里,轮换到下一分钟前调用: usb和内部相机

---
 app/src/main/java/com/safeluck/floatwindow/util/FileUtil.java                      |  174 +++++++++++++++-------------------
 app/src/main/java/com/safeluck/floatwindow/util/VideoFileUtils.java                |    2 
 app/src/main/java/com/safeluck/floatwindow/manager/AndroidCameraRecordManager.java |   45 ++++++++
 app/src/main/java/com/safeluck/floatwindow/manager/UsbCameraRecordManager.java     |   49 ++++++++-
 4 files changed, 164 insertions(+), 106 deletions(-)

diff --git a/app/src/main/java/com/safeluck/floatwindow/manager/AndroidCameraRecordManager.java b/app/src/main/java/com/safeluck/floatwindow/manager/AndroidCameraRecordManager.java
index ecc72ef..ce8aec6 100644
--- a/app/src/main/java/com/safeluck/floatwindow/manager/AndroidCameraRecordManager.java
+++ b/app/src/main/java/com/safeluck/floatwindow/manager/AndroidCameraRecordManager.java
@@ -22,6 +22,7 @@
 import com.safeluck.floatwindow.MediaArgu;
 import com.safeluck.floatwindow.ResponseVO;
 import com.safeluck.floatwindow.util.VideoFileUtils;
+import com.safeluck.floatwindow.util.FileUtil;
 
 import timber.log.Timber;
 
@@ -266,12 +267,15 @@
                     // 鍋滄褰撳墠褰曞儚
                     stopCurrentRecording();
                     
-                    // 閫氱煡鏂囦欢鍒涘缓
+                    // 閫氱煡鏂囦欢鍒涘缓锛堝綋鍓嶈繖娈� 1 鍒嗛挓鏂囦欢锛�
                     if (currentVideoFile != null) {
                         notifyCallback(2, 0, currentVideoFile.getName());
                     }
-                    
-                    // 寮�濮嬫柊鐨勫綍鍍�
+
+                    // 姣忔鍐欏叆鏂版枃浠跺墠锛屾鏌ュ苟娓呯悊瀛樺偍绌洪棿锛圓nYun_VIDEO 涓嬬殑 mp4锛�
+                    ensureStorageSpaceForMp4();
+
+                    // 寮�濮嬫柊鐨勫綍鍍忥紙鍒涘缓涓嬩竴鍒嗛挓鐨勬柊鏂囦欢锛�
                     startRecording();
                     
                     // 缁х画瀹氭椂
@@ -280,6 +284,41 @@
             }
         }, RECORD_INTERVAL_MS);
     }
+
+    /**
+     * 纭繚瀛樺偍绌洪棿瓒冲锛堥拡瀵� AnYun_VIDEO 涓嬬殑 mp4锛�
+     * TF 鍗★細浣跨敤 FileUtil.cleanupH264Files锛堝唴閮ㄥ凡鏀逛负娓呯悊 mp4锛夋寜鏃ユ湡鐩綍鍒犻櫎鏈�鏃╃殑瑙嗛
+     * 鍐呴儴 Flash锛氫娇鐢� FileUtil.ensureInternalFlashSpaceForH264锛堝唴閮ㄥ凡鏀逛负娓呯悊 mp4锛�
+     */
+    private void ensureStorageSpaceForMp4() {
+        if (context == null || mediaArgu == null) {
+            return;
+        }
+        try {
+            int tfFlag = mediaArgu.getTfCardFlag(); // 0-鍐呴儴瀛樺偍锛�1-TF 鍗�
+
+            // 鍏堝畾浣嶅綋鍓嶄娇鐢ㄧ殑鏃ユ湡鐩綍锛屽啀鍙栧叾鐖剁洰褰� AnYun_VIDEO 浣滀负鏍圭洰褰�
+            File dateDir = VideoFileUtils.getVideoDirectory(context, tfFlag);
+            if (dateDir == null) {
+                return;
+            }
+            File rootDir = dateDir.getParentFile(); // .../AnYun_VIDEO
+            if (rootDir == null) {
+                return;
+            }
+
+            String rootPath = rootDir.getAbsolutePath();
+            if (tfFlag == 1) {
+                // TF 鍗★細闄愬埗鎬诲ぇ灏� + 鍓╀綑绌洪棿
+                FileUtil.cleanupH264Files(context, rootPath);
+            } else {
+                // 鍐呴儴 Flash锛氱‘淇濆墿浣欑┖闂� 鈮� 800MB
+                FileUtil.ensureInternalFlashSpaceForH264(context);
+            }
+        } catch (Exception e) {
+            Timber.e(e, "ensureStorageSpaceForMp4 error");
+        }
+    }
     
     /**
      * 鍋滄褰撳墠褰曞儚
diff --git a/app/src/main/java/com/safeluck/floatwindow/manager/UsbCameraRecordManager.java b/app/src/main/java/com/safeluck/floatwindow/manager/UsbCameraRecordManager.java
index 0f56508..cb11b44 100644
--- a/app/src/main/java/com/safeluck/floatwindow/manager/UsbCameraRecordManager.java
+++ b/app/src/main/java/com/safeluck/floatwindow/manager/UsbCameraRecordManager.java
@@ -17,6 +17,7 @@
 import com.safeluck.floatwindow.MediaArgu;
 import com.safeluck.floatwindow.ResponseVO;
 import com.safeluck.floatwindow.util.GlobalData;
+import com.safeluck.floatwindow.util.FileUtil;
 import com.safeluck.floatwindow.util.VideoFileUtils;
 
 import timber.log.Timber;
@@ -572,14 +573,17 @@
                         
                         // 閲婃斁褰撳墠璧勬簮
                         releaseResources();
-                        
+
                         // 閲嶅懡鍚嶅垰瀹屾垚鐨勬枃浠�
                         if (completedVideoFile != null) {
                             renameCompletedFile(completedVideoFile);
                             completedVideoFile = null;
                         }
-                        
-                        // 鍒濆鍖栨柊鐨勭紪鐮佸櫒鍜孧uxer
+
+                        // 姣忔鍐欏叆鏂版枃浠跺墠锛屾鏌ュ苟娓呯悊瀛樺偍绌洪棿锛圓nYun_VIDEO 涓嬬殑 mp4锛�
+                        ensureStorageSpaceForMp4();
+
+                        // 鍒濆鍖栨柊鐨勭紪鐮佸櫒鍜孧uxer锛堝垱寤轰笅涓�鍒嗛挓鐨勬柊鏂囦欢锛�
                         if (!initEncoderAndMuxer()) {
                             Timber.e("Failed to create new video file");
                             break;
@@ -647,13 +651,13 @@
                 }
                 
                 releaseResources();
-                
+
                 // 閲嶅懡鍚嶅垰瀹屾垚鐨勬枃浠讹紙鍋滄褰曞儚鏃讹級
                 if (completedVideoFile != null) {
                     renameCompletedFile(completedVideoFile);
                     completedVideoFile = null;
                 }
-                
+
                 Timber.d("RecordThread ended");
             }
         }
@@ -811,6 +815,41 @@
         // 濡傛灉鑾峰彇澶辫触锛岃繑鍥為粯璁ゅ��60绉�
         return 60;
     }
+
+    /**
+     * 纭繚瀛樺偍绌洪棿瓒冲锛堥拡瀵� AnYun_VIDEO 涓嬬殑 mp4锛�
+     * TF 鍗★細浣跨敤 FileUtil.cleanupH264Files锛堝唴閮ㄥ凡鏀逛负娓呯悊 mp4锛夋寜鏃ユ湡鐩綍鍒犻櫎鏈�鏃╃殑瑙嗛
+     * 鍐呴儴 Flash锛氫娇鐢� FileUtil.ensureInternalFlashSpaceForH264锛堝唴閮ㄥ凡鏀逛负娓呯悊 mp4锛�
+     */
+    private void ensureStorageSpaceForMp4() {
+        if (context == null || mediaArgu == null) {
+            return;
+        }
+        try {
+            int tfFlag = mediaArgu.getTfCardFlag(); // 0-鍐呴儴瀛樺偍锛�1-TF 鍗�
+
+            // 鍏堝畾浣嶅綋鍓嶄娇鐢ㄧ殑鏃ユ湡鐩綍锛屽啀鍙栧叾鐖剁洰褰� AnYun_VIDEO 浣滀负鏍圭洰褰�
+            File dateDir = VideoFileUtils.getVideoDirectory(context, tfFlag);
+            if (dateDir == null) {
+                return;
+            }
+            File rootDir = dateDir.getParentFile(); // .../AnYun_VIDEO
+            if (rootDir == null) {
+                return;
+            }
+
+            String rootPath = rootDir.getAbsolutePath();
+            if (tfFlag == 1) {
+                // TF 鍗★細闄愬埗鎬诲ぇ灏� + 鍓╀綑绌洪棿
+                FileUtil.cleanupH264Files(context, rootPath);
+            } else {
+                // 鍐呴儴 Flash锛氱‘淇濆墿浣欑┖闂� 鈮� 800MB
+                FileUtil.ensureInternalFlashSpaceForH264(context);
+            }
+        } catch (Exception e) {
+            Timber.e(e, "ensureStorageSpaceForMp4 error");
+        }
+    }
     
     /**
      * 妫�鏌ュ苟鍚姩Muxer
diff --git a/app/src/main/java/com/safeluck/floatwindow/util/FileUtil.java b/app/src/main/java/com/safeluck/floatwindow/util/FileUtil.java
index 1bbac4f..d0bf763 100644
--- a/app/src/main/java/com/safeluck/floatwindow/util/FileUtil.java
+++ b/app/src/main/java/com/safeluck/floatwindow/util/FileUtil.java
@@ -58,23 +58,24 @@
     }
 
     /**
-     * 娓呯悊 TF 鍗′笂鐨� h264 鏂囦欢
-     * 褰� h264 鏂囦欢鎬诲ぇ灏忚秴杩囨寚瀹氶槇鍊兼垨 TF 鍗″墿浣欑┖闂村皬浜庢寚瀹氬�兼椂锛屽垹闄ゆ棩鏈熸渶鏃╃殑鏂囦欢澶�
-     * 
-     * @param context Context 瀵硅薄锛岀敤浜庤幏鍙� TF 鍗¤矾寰勫拰鍓╀綑绌洪棿
-     * @param h264RootDir h264 鏍圭洰褰曡矾寰勶紝渚嬪 "/sdcard/h264"
+     * 娓呯悊 TF 鍗′笂鐨� MP4 鏂囦欢锛堜緥濡� AnYun_VIDEO 鐩綍锛�
+     * 褰� MP4 鏂囦欢鎬诲ぇ灏忚秴杩囨寚瀹氶槇鍊兼垨 TF 鍗″墿浣欑┖闂村皬浜庢寚瀹氬�兼椂锛屽垹闄ゆ棩鏈熸渶鏃╃殑鏂囦欢澶�
+     *
+     * @param context      Context 瀵硅薄锛岀敤浜庤幏鍙� TF 鍗¤矾寰勫拰鍓╀綑绌洪棿
+     * @param mp4RootDir   MP4 鏍圭洰褰曡矾寰勶紝渚嬪 "/storage/XXXX-XXXX/AnYun_VIDEO"
      * @param maxTotalSizeGB 鏈�澶ф�诲ぇ灏忥紙GB锛夛紝榛樿 5GB
      * @param minFreeSpaceGB 鏈�灏忓墿浣欑┖闂达紙GB锛夛紝榛樿 1GB
      */
-    public static void cleanupH264Files(Context context, String h264RootDir, long maxTotalSizeGB, long minFreeSpaceGB) {
-        if (context == null || h264RootDir == null || h264RootDir.trim().isEmpty()) {
-            Timber.w("Context or h264 root directory is null, skip cleanup");
+    public static void cleanupH264Files(Context context, String mp4RootDir, long maxTotalSizeGB, long minFreeSpaceGB) {
+        // 娉ㄦ剰锛氫负浜嗗吋瀹规棫浠g爜锛屾柟娉曞悕浠嶇劧鍙� cleanupH264Files锛屼絾宸茬粡鏀逛负娓呯悊 MP4 鏂囦欢
+        if (context == null || mp4RootDir == null || mp4RootDir.trim().isEmpty()) {
+            Timber.w("Context or mp4 root directory is null, skip cleanup");
             return;
         }
 
-        File h264Root = new File(h264RootDir);
-        if (!h264Root.exists() || !h264Root.isDirectory()) {
-            Timber.d("H264 root directory does not exist: %s, skip cleanup", h264RootDir);
+        File mp4Root = new File(mp4RootDir);
+        if (!mp4Root.exists() || !mp4Root.isDirectory()) {
+            Timber.d("MP4 root directory does not exist: %s, skip cleanup", mp4RootDir);
             return;
         }
 
@@ -91,23 +92,24 @@
             Timber.d("TF card free space: %d GB", freeSpaceGB);
 
             // 鎵弿鎵�鏈夋棩鏈熸枃浠跺す
-            File[] dateDirs = h264Root.listFiles(File::isDirectory);
+            File[] dateDirs = mp4Root.listFiles(File::isDirectory);
             if (dateDirs == null || dateDirs.length == 0) {
-                Timber.d("No date directories found in h264 root: %s", h264RootDir);
+                Timber.d("No date directories found in mp4 root: %s", mp4RootDir);
                 return;
             }
 
             // 鎸夋棩鏈熸帓搴忥紙鏈�鏃╃殑鍦ㄥ墠锛�
             List<DateDirInfo> dateDirList = new ArrayList<>();
-            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd", Locale.CHINA);
+            // AnYun_VIDEO 浣跨敤鐨勬槸 yyyy_MM_dd 鐩綍鍚嶏紝渚嬪 2026_01_30
+            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy_MM_dd", Locale.CHINA);
             
             for (File dateDir : dateDirs) {
                 String dirName = dateDir.getName();
-                // 鍙鐞嗙鍚堟棩鏈熸牸寮忕殑鏂囦欢澶癸紙yyyyMMdd锛�
-                if (dirName.length() == 8 && dirName.matches("\\d{8}")) {
+                // 鍙鐞嗙鍚堟棩鏈熸牸寮忕殑鏂囦欢澶癸紙yyyy_MM_dd锛屼緥濡� 2026_01_30锛�
+                if (dirName.matches("\\d{4}_\\d{2}_\\d{2}")) {
                     try {
                         Date date = dateFormat.parse(dirName);
-                        long totalSize = calculateH264FilesSize(dateDir);
+                        long totalSize = calculateMp4FilesSize(dateDir);
                         dateDirList.add(new DateDirInfo(dateDir, date, totalSize));
                     } catch (ParseException e) {
                         Timber.w("Invalid date directory name: %s", dirName);
@@ -128,7 +130,7 @@
             for (DateDirInfo info : dateDirList) {
                 totalSizeGB += info.totalSize / (1024L * 1024L * 1024L);
             }
-            Timber.d("Total h264 files size: %d GB, Max allowed: %d GB", totalSizeGB, maxTotalSizeGB);
+            Timber.d("Total mp4 files size: %d GB, Max allowed: %d GB", totalSizeGB, maxTotalSizeGB);
             Timber.d("TF card free space: %d GB, Min required: %d GB", freeSpaceGB, minFreeSpaceGB);
 
             // 妫�鏌ユ槸鍚﹂渶瑕佹竻鐞�
@@ -172,19 +174,20 @@
     }
 
     /**
-     * 娓呯悊 TF 鍗′笂鐨� h264 鏂囦欢锛堜娇鐢ㄩ粯璁ゅ弬鏁帮細鏈�澶�5GB锛屾渶灏忓墿浣欑┖闂�1GB锛�
+     * 娓呯悊 TF 鍗′笂鐨� MP4 鏂囦欢锛堜娇鐢ㄩ粯璁ゅ弬鏁帮細鏈�澶�5GB锛屾渶灏忓墿浣欑┖闂�1GB锛�
      */
-    public static void cleanupH264Files(Context context, String h264RootDir) {
-        cleanupH264Files(context, h264RootDir, 5, 1);
+    public static void cleanupH264Files(Context context, String mp4RootDir) {
+        // 涓哄吋瀹规棫璋冪敤淇濈暀鏂规硶鍚嶏紝鍐呴儴宸叉敼涓哄鐞� MP4
+        cleanupH264Files(context, mp4RootDir, 5, 1);
     }
 
     /**
-     * 妫�鏌ュ唴閮� Flash锛堥潪 TF 鍗★級鍓╀綑绌洪棿锛屽鏋滃皬浜� 800MB锛屽垯鎸夋椂闂撮『搴忓垹闄� h264_*.h264 鏂囦欢
-     * 鐩綍锛歝ontext.getExternalFilesDir(null).getAbsolutePath()
-     * 鏂囦欢鍚嶆牸寮忕ず渚嬶細h264_1735023032000.h264銆乭264_camera2_1735023032000.h264
+     * 妫�鏌ュ唴閮� Flash锛堥潪 TF 鍗★級鍓╀綑绌洪棿锛屽鏋滃皬浜� 800MB锛屽垯鎸夋椂闂撮『搴忓垹闄� AnYun_VIDEO 涓嬫渶鏃╃殑 MP4 鏂囦欢
+     * 鐩綍缁撴瀯绀轰緥锛�/sdcard/AnYun_VIDEO/yyMMdd/HHmmss_xxx.mp4
      *
      * 鍒犻櫎瑙勫垯锛�
-     * - 鎸夋枃浠跺悕涓殑鏃堕棿鎴充粠灏忓埌澶э紙瓒婃棭瓒婂厛鍒狅級渚濇鍒犻櫎
+     * - 閫掑綊閬嶅巻 AnYun_VIDEO 鐩綍锛屾敹闆嗘墍鏈� .mp4 鏂囦欢
+     * - 鎸� lastModified 鏃堕棿浠庢棭鍒版櫄鎺掑簭锛堣秺鏃╄秺鍏堝垹锛�
      * - 姣忓垹闄や竴娆″悗閲嶆柊璁$畻鍓╀綑绌洪棿锛岀洿鍒� 鈮� 800MB 鎴栨枃浠跺垹瀹�
      *
      * 杩斿洖鍊硷細
@@ -197,13 +200,21 @@
             return 0;
         }
 
-        File externalDir = context.getExternalFilesDir(null);
-        if (externalDir == null) {
-            Timber.w("ensureInternalFlashSpaceForH264: external files dir is null");
+        // 鍐呴儴瀛樺偍鏍圭洰褰曪紙涓� VideoFileUtils 涓繚鎸佷竴鑷达級
+        File externalRoot = android.os.Environment.getExternalStorageDirectory();
+        if (externalRoot == null) {
+            Timber.w("ensureInternalFlashSpaceForH264: external storage dir is null");
             return 0;
         }
 
-        String basePath = externalDir.getAbsolutePath();
+        // AnYun_VIDEO 鏍圭洰褰�
+        File anyunRoot = new File(externalRoot, "AnYun_VIDEO");
+        if (!anyunRoot.exists() || !anyunRoot.isDirectory()) {
+            Timber.w("ensureInternalFlashSpaceForH264: AnYun_VIDEO dir not found -> %s", anyunRoot.getAbsolutePath());
+            return 0;
+        }
+
+        String basePath = anyunRoot.getAbsolutePath();
         long minFreeBytes = 800L * 1024L * 1024L; // 800MB
 
         long freeBytes = getFreeSpaceBytes(basePath);
@@ -214,85 +225,32 @@
             return 0;
         }
 
-        // 鏀堕泦绗﹀悎鍛藉悕瑙勫垯鐨� h264 鏂囦欢
-        File[] files = externalDir.listFiles();
-        if (files == null || files.length == 0) {
-            Timber.w("ensureInternalFlashSpaceForH264: no files in dir -> %s", basePath);
+        // 鏀堕泦鎵�鏈� .mp4 鏂囦欢
+        List<File> mp4Files = new ArrayList<>();
+        collectMp4Files(anyunRoot, mp4Files);
+        if (mp4Files.isEmpty()) {
+            Timber.w("ensureInternalFlashSpaceForH264: no mp4 files in dir -> %s", basePath);
             // 宸茬粡娌℃湁鍙垹鐨勬枃浠讹紝濡傛灉浠嶅皬浜� 800MB锛屽垯鐩存帴杩斿洖 -1
             return freeBytes >= minFreeBytes ? 0 : -1;
         }
 
-        class H264FileInfo {
-            File file;
-            long timestamp;
-
-            H264FileInfo(File file, long timestamp) {
-                this.file = file;
-                this.timestamp = timestamp;
-            }
-        }
-
-        List<H264FileInfo> h264Files = new ArrayList<>();
-        for (File file : files) {
-            if (!file.isFile()) {
-                continue;
-            }
-
-            String name = file.getName();
-            // 鍙鐞� .h264 缁撳熬锛屼笖浠� h264_ 寮�澶寸殑鏂囦欢
-            if (!name.toLowerCase(Locale.CHINA).endsWith(".h264")) {
-                continue;
-            }
-            if (!name.startsWith("h264_") && !name.startsWith("h264_camera2_")) {
-                continue;
-            }
-
-            // 鎻愬彇鏃堕棿鎴抽儴鍒�
-            String timePart = null;
-            if (name.startsWith("h264_camera2_")) {
-                // 鍓嶇紑闀垮害 13锛�"h264_camera2_"
-                timePart = name.substring("h264_camera2_".length(), name.length() - ".h264".length());
-            } else if (name.startsWith("h264_")) {
-                // 鍓嶇紑闀垮害 5锛�"h264_"
-                timePart = name.substring("h264_".length(), name.length() - ".h264".length());
-            }
-
-            if (timePart == null || timePart.isEmpty()) {
-                continue;
-            }
-
-            try {
-                long ts = Long.parseLong(timePart);
-                h264Files.add(new H264FileInfo(file, ts));
-            } catch (NumberFormatException e) {
-                // 鏂囦欢鍚嶄笉绗﹀悎鏃堕棿鎴虫牸寮忥紝璺宠繃
-                Timber.w("ensureInternalFlashSpaceForH264: invalid timestamp in file name -> %s", name);
-            }
-        }
-
-        if (h264Files.isEmpty()) {
-            Timber.w("ensureInternalFlashSpaceForH264: no matched h264 files in -> %s", basePath);
-            return freeBytes >= minFreeBytes ? 0 : -1;
-        }
-
-        // 鎸夋椂闂存埑鍗囧簭鎺掑垪锛堣秺鏃╃殑瓒婂厛鍒狅級
-        Collections.sort(h264Files, new Comparator<H264FileInfo>() {
+        // 鎸� lastModified 鍗囧簭鎺掑垪锛堣秺鏃╃殑瓒婂厛鍒狅級
+        Collections.sort(mp4Files, new Comparator<File>() {
             @Override
-            public int compare(H264FileInfo o1, H264FileInfo o2) {
-                return Long.compare(o1.timestamp, o2.timestamp);
+            public int compare(File o1, File o2) {
+                return Long.compare(o1.lastModified(), o2.lastModified());
             }
         });
 
         int deletedCount = 0;
-        for (H264FileInfo info : h264Files) {
+        for (File f : mp4Files) {
             if (freeBytes >= minFreeBytes) {
                 break;
             }
 
-            File f = info.file;
             long size = f.length();
-            Timber.d("ensureInternalFlashSpaceForH264: deleting file -> %s, size=%d, ts=%d",
-                    f.getAbsolutePath(), size, info.timestamp);
+            Timber.d("ensureInternalFlashSpaceForH264: deleting mp4 file -> %s, size=%d",
+                    f.getAbsolutePath(), size);
 
             if (f.delete()) {
                 deletedCount++;
@@ -310,14 +268,14 @@
     }
 
     /**
-     * 璁$畻鐩綍涓嬫墍鏈� .h264 鏂囦欢鐨勬�诲ぇ灏忥紙瀛楄妭锛�
+     * 璁$畻鐩綍涓嬫墍鏈� .mp4 鏂囦欢鐨勬�诲ぇ灏忥紙瀛楄妭锛�
      */
-    private static long calculateH264FilesSize(File dir) {
+    private static long calculateMp4FilesSize(File dir) {
         long totalSize = 0;
         File[] files = dir.listFiles();
         if (files != null) {
             for (File file : files) {
-                if (file.isFile() && file.getName().toLowerCase().endsWith(".h264")) {
+                if (file.isFile() && file.getName().toLowerCase().endsWith(".mp4")) {
                     totalSize += file.length();
                 }
             }
@@ -342,6 +300,28 @@
     }
 
     /**
+     * 閫掑綊鏀堕泦鐩綍涓嬫墍鏈� .mp4 鏂囦欢
+     */
+    private static void collectMp4Files(File dir, List<File> outList) {
+        if (dir == null || !dir.exists()) {
+            return;
+        }
+
+        File[] files = dir.listFiles();
+        if (files == null) {
+            return;
+        }
+
+        for (File f : files) {
+            if (f.isDirectory()) {
+                collectMp4Files(f, outList);
+            } else if (f.isFile() && f.getName().toLowerCase(Locale.CHINA).endsWith(".mp4")) {
+                outList.add(f);
+            }
+        }
+    }
+
+    /**
      * 鑾峰彇鎸囧畾璺緞鐨勫墿浣欑┖闂达紙瀛楄妭锛�
      */
     private static long getFreeSpaceBytes(String path) {
diff --git a/app/src/main/java/com/safeluck/floatwindow/util/VideoFileUtils.java b/app/src/main/java/com/safeluck/floatwindow/util/VideoFileUtils.java
index 5979e3c..cf3cb71 100644
--- a/app/src/main/java/com/safeluck/floatwindow/util/VideoFileUtils.java
+++ b/app/src/main/java/com/safeluck/floatwindow/util/VideoFileUtils.java
@@ -49,7 +49,7 @@
             }
         }
         
-        // 鍒涘缓骞存湀鏃ョ洰褰曪紙渚嬪锛�260126锛�
+        // 鍒涘缓骞存湀鏃ョ洰褰曪紙渚嬪锛�2026_01_30锛�
         SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy_MM_dd", Locale.getDefault());
         String dateDirName = dateFormat.format(new Date());
         File dateDir = new File(videoDir, dateDirName);

--
Gitblit v1.8.0