From e4b7cbea399e3dcc40011eaa2d2fe25696d7e894 Mon Sep 17 00:00:00 2001
From: Dana <Dana_Lee1016@126.com>
Date: 星期四, 04 十二月 2025 16:57:19 +0800
Subject: [PATCH] 1.可以先见h264 写入文件。再发推流都可以;边录边推

---
 app/src/main/java/com/anyun/h264/H264EncodeService.java    |  183 ++++++++++++++++++++++-----------------------
 app/src/main/java/com/anyun/h264/H264Encoder.java          |   12 +++
 app/src/main/java/com/anyun/h264/JT1076ProtocolHelper.java |   12 ++
 3 files changed, 114 insertions(+), 93 deletions(-)

diff --git a/app/src/main/java/com/anyun/h264/H264EncodeService.java b/app/src/main/java/com/anyun/h264/H264EncodeService.java
index c2655fa..afa5257 100644
--- a/app/src/main/java/com/anyun/h264/H264EncodeService.java
+++ b/app/src/main/java/com/anyun/h264/H264EncodeService.java
@@ -36,7 +36,7 @@
     private H264FileTransmitter h264FileTransmitter; // H264鏂囦欢浼犺緭鍣�
     private String outputFileDirectory; // H264鏂囦欢杈撳嚭鐩綍
     private WatermarkInfo currentWatermarkInfo; // 褰撳墠姘村嵃淇℃伅
-    private static final int H264_FILE_RETENTION_DAYS = 5; // 鍙牴鎹渶姹傝皟鏁翠负3鎴�5澶�
+    private static final int H264_FILE_RETENTION_DAYS = 1; // 鍙牴鎹渶姹傝皟鏁翠负3鎴�5澶�
     
     // 澶氳繘绋嬫敮鎸侊細绗簩涓憚鍍忓ご鐨勬湇鍔¤繛鎺�
     private IH264EncodeService camera2Service;
@@ -141,6 +141,8 @@
                 config.width = DEFAULT_WIDTH;
                 config.height = DEFAULT_HEIGHT;
                 config.framerate = DEFAULT_FRAME_RATE;
+                config.enableFileOutput = false;
+                config.enableNetworkTransmit = false;
                 config.ip = null;
                 config.port = 0;
                 config.simPhone = null;
@@ -152,6 +154,8 @@
             config.width = json.optInt("width", DEFAULT_WIDTH);
             config.height = json.optInt("height", DEFAULT_HEIGHT);
             config.framerate = json.optInt("framerate", DEFAULT_FRAME_RATE);
+            config.enableFileOutput = json.optBoolean("enableFileOutput", false);
+            config.enableNetworkTransmit = json.optBoolean("enableNetworkTransmit", false);
             config.ip = json.optString("ip", null);
             config.port = json.optInt("port", 0);
             config.simPhone = json.optString("simPhone", null);
@@ -240,7 +244,9 @@
                 case 0: // 寮�鍚痟264鏂囦欢鍐欏叆
                     try {
                         EncodeConfig config0 = EncodeConfig.fromJson(jsonConfig);
-                        return startFileEncode(config0);
+                        config0.enableFileOutput = true;
+                        config0.enableNetworkTransmit = false;
+                        return startEncode(config0);
                     } catch (JSONException e) {
                         Timber.e(e, "Failed to parse JSON config: %s", jsonConfig);
                         return 1;
@@ -253,21 +259,35 @@
                     }
                     return stopEncoder();
                     
-                case 2: // 寮�鍚綉缁滄帹閫乭264锛堜笉鍐欏叆鏂囦欢锛�
+                case 2: // 寮�鍚綉缁滄帹閫乭264锛堝彲鍚屾椂鍐欏叆鏂囦欢锛�
                     try {
                         EncodeConfig config2 = EncodeConfig.fromJson(jsonConfig);
-                        return startNetworkEncode(config2);
+                        // 妫�鏌ュ繀闇�鐨勯厤缃弬鏁�
+                        if (config2 == null || config2.ip == null || config2.ip.trim().isEmpty() || config2.port <= 0) {
+                            Timber.e("Network encode requires valid ip and port in config");
+                            return 1; // 澶辫触
+                        }
+                        config2.enableNetworkTransmit = true;
+                        return startEncode(config2);
                     } catch (JSONException e) {
                         Timber.e(e, "Failed to parse JSON config: %s", jsonConfig);
                         return 1;
                     }
                     
-                case 3: // 鍋滄h264缂栫爜骞跺仠姝㈢綉缁滄帹閫�
+                case 3: // 鍋滄缃戠粶鎺ㄩ�侊紙淇濇寔鏂囦欢鍐欏叆锛�
                     // 妫�鏌ユ槸鍚︽寚瀹氫簡cameraId=2
                     if (cameraId != null && cameraId == 2) {
                         return controlEncodeInProcess2(action, jsonConfig);
                     }
-                    return stopEncoder();
+                    // 鍙叧闂綉缁滀紶杈擄紝淇濇寔鏂囦欢鍐欏叆
+                    if (h264Encoder != null) {
+                        h264Encoder.setEnableNetworkTransmission(false);
+                        Timber.d("Network transmission stopped, file output continues");
+                        return 0;
+                    } else {
+                        Timber.w("Encoder is not running");
+                        return 0; // 鎴愬姛锛堟病鏈夎繍琛岀殑缂栫爜鍣紝瑙嗕负鎴愬姛锛�
+                    }
                     
                 case 4: // 寮�濮嬩紶杈揌264鏂囦欢
                     try {
@@ -376,35 +396,82 @@
     }
     
     /**
-     * 鍚姩鏂囦欢缂栫爜妯″紡锛堝彧鍐欏叆鏂囦欢锛屼笉杩涜缃戠粶鎺ㄩ�侊級
+     * 鍚姩缂栫爜锛堢粺涓�鏂规硶锛屾敮鎸佹枃浠跺啓鍏ュ拰缃戠粶浼犺緭鐨勭粍鍚堬級
+     * @param config 缂栫爜閰嶇疆
+     * @return 0-鎴愬姛锛�1-澶辫触
      */
-    private int startFileEncode(EncodeConfig config) {
-        Timber.d("Starting file encode mode");
+    private int startEncode(EncodeConfig config) {
+        if (config == null) {
+            Timber.e("Encode config cannot be null");
+            return 1;
+        }
+        Timber.d("Starting encode mode, fileOutput: %b, networkTransmit: %b",
+                config.enableFileOutput, config.enableNetworkTransmit);
         
-        // 濡傛灉缂栫爜鍣ㄥ凡缁忓湪杩愯锛屽厛鍋滄
+        // 濡傛灉缂栫爜鍣ㄥ凡缁忓湪杩愯锛屽彧鏇存柊閰嶇疆
         if (h264Encoder != null) {
-            Timber.w("Encoder is already running, stopping it first");
-            stopEncoder();
+            Timber.d("Encoder is already running, updating configuration");
+            try {
+                h264Encoder.setEnableFileOutput(config.enableFileOutput);
+
+                
+                // 濡傛灉寮�鍚綉缁滀紶杈擄紝闇�瑕佽缃湇鍔″櫒鍦板潃鍜屽崗璁弬鏁�
+                if (config.enableNetworkTransmit) {
+                    if (config == null || config.ip == null || config.ip.trim().isEmpty() || config.port <= 0) {
+                        Timber.e("Network transmit requires valid ip and port in config");
+                        return 1; // 澶辫触
+                    }
+                    h264Encoder.setServerAddress(config.ip, config.port);
+                    
+                    // 璁剧疆鍗忚鍙傛暟锛堜娇鐢ㄩ厤缃腑鐨剆imPhone锛屽鏋滄湭鎻愪緵鍒欎娇鐢ㄩ粯璁ゅ�硷級
+                    String simPhone = config.simPhone != null && !config.simPhone.trim().isEmpty() 
+                            ? config.simPhone : "013120122580";
+                    h264Encoder.setProtocolParams(simPhone, (byte)1);
+                }
+                h264Encoder.setEnableNetworkTransmission(config.enableNetworkTransmit);
+                Timber.d("Encoder configuration updated successfully");
+                return 0; // 鎴愬姛
+            } catch (Exception e) {
+                Timber.e(e, "Error updating encoder configuration");
+                return 1; // 澶辫触
+            }
         }
         
+        // 缂栫爜鍣ㄦ湭杩愯锛岄渶瑕佸垵濮嬪寲骞跺惎鍔�
         try {
+            // 濡傛灉寮�鍚綉缁滀紶杈擄紝妫�鏌ュ繀闇�鐨勯厤缃弬鏁�
+        if (config.enableNetworkTransmit) {
+                if (config == null || config.ip == null || config.ip.trim().isEmpty() || config.port <= 0) {
+                    Timber.e("Network transmit requires valid ip and port in config");
+                    return 1; // 澶辫触
+                }
+            }
+            
             // 鍒涘缓缂栫爜鍣�
             h264Encoder = new H264Encoder();
             
             // 璁剧疆缂栫爜鍙傛暟锛堜娇鐢ㄩ厤缃腑鐨勫弬鏁帮級
             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);
 
             // 璁剧疆杈撳嚭鏂囦欢鐩綍锛圚264Encoder浼氳嚜鍔ㄧ鐞嗘枃浠跺垱寤猴紝姣忓垎閽熶竴涓枃浠讹級
             // 浣跨敤涓�涓复鏃舵枃浠跺悕鏉ヨ缃洰褰曪紝H264Encoder浼氬湪鍒濆鍖栨椂鍒涘缓绗竴涓枃浠�
             File tempFile = new File(outputFileDirectory, "temp.h264");
-            h264Encoder.setOutputFile(tempFile.getAbsolutePath());
-            h264Encoder.setEnableFileOutput(true); // 鍚敤鏂囦欢杈撳嚭
+        h264Encoder.setOutputFile(tempFile.getAbsolutePath());
+        h264Encoder.setEnableFileOutput(config.enableFileOutput);
             
-            // 绂佺敤缃戠粶浼犺緭
-            h264Encoder.setEnableNetworkTransmission(false);
+            // 璁剧疆缃戠粶浼犺緭
+        h264Encoder.setEnableNetworkTransmission(config.enableNetworkTransmit);
+        if (config.enableNetworkTransmit) {
+                h264Encoder.setServerAddress(config.ip, config.port);
+                
+                // 璁剧疆鍗忚鍙傛暟锛堜娇鐢ㄩ厤缃腑鐨剆imPhone锛屽鏋滄湭鎻愪緵鍒欎娇鐢ㄩ粯璁ゅ�硷級
+                String simPhone = config.simPhone != null && !config.simPhone.trim().isEmpty() 
+                        ? config.simPhone : "013120122580";
+                h264Encoder.setProtocolParams(simPhone, (byte)1);
+            }
             
             // 鍒濆鍖栧苟鍚姩锛堜娇鐢ㄩ厤缃腑鐨勫垎杈ㄧ巼锛�
             // 鏍规嵁cameraId閫夋嫨鎽勫儚澶磋寖鍥�
@@ -418,79 +485,11 @@
                     Timber.d("Applied saved watermark info to encoder");
                 }
                 h264Encoder.start();
-                Timber.d("File encode started successfully, output directory: %s, resolution: %dx%d, framerate: %d", 
-                        outputFileDirectory, width, height, framerate);
-                return 0; // 鎴愬姛
-            } else {
-                Timber.e("Failed to initialize encoder");
-                h264Encoder = null;
-                return 1; // 澶辫触
-            }
-        } catch (Exception e) {
-            Timber.e(e, "Failed to start file encode");
-            h264Encoder = null;
-            return 1; // 澶辫触
-        }
-    }
-    
-    /**
-     * 鍚姩缃戠粶鎺ㄩ�佹ā寮忥紙鍙繘琛岀綉缁滄帹閫侊紝涓嶅啓鍏ユ枃浠讹級
-     */
-    private int startNetworkEncode(EncodeConfig config) {
-        Timber.d("Starting network encode mode");
-        
-        // 濡傛灉缂栫爜鍣ㄥ凡缁忓湪杩愯锛屽厛鍋滄
-        if (h264Encoder != null) {
-            Timber.w("Encoder is already running, stopping it first");
-            stopEncoder();
-        }
-        
-        // 妫�鏌ュ繀闇�鐨勯厤缃弬鏁�
-        if (config == null || config.ip == null || config.ip.trim().isEmpty() || config.port <= 0) {
-            Timber.e("Network encode requires valid ip and port in config");
-            return 1; // 澶辫触
-        }
-        
-        try {
-            // 鍒涘缓缂栫爜鍣�
-            h264Encoder = new H264Encoder();
-            
-            // 璁剧疆缂栫爜鍙傛暟锛堜娇鐢ㄩ厤缃腑鐨勫弬鏁帮級
-            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;
-            h264Encoder.setEncoderParams(width, height, framerate, DEFAULT_BITRATE);
-
-            // 璁剧疆杈撳嚭鏂囦欢鐩綍锛圚264Encoder浼氳嚜鍔ㄧ鐞嗘枃浠跺垱寤猴紝姣忓垎閽熶竴涓枃浠讹級
-            // 浣跨敤涓�涓复鏃舵枃浠跺悕鏉ヨ缃洰褰曪紝H264Encoder浼氬湪鍒濆鍖栨椂鍒涘缓绗竴涓枃浠�
-            File tempFile = new File(outputFileDirectory, "temp.h264");
-            h264Encoder.setOutputFile(tempFile.getAbsolutePath());
-            h264Encoder.setEnableFileOutput(config.enableFileOutput); // 鍚敤鏂囦欢杈撳嚭
-
-            
-            // 鍚敤缃戠粶浼犺緭骞惰缃湇鍔″櫒鍦板潃
-            h264Encoder.setEnableNetworkTransmission(config.enableNetworkTransmit);
-            h264Encoder.setServerAddress(config.ip, config.port);
-            
-            // 璁剧疆鍗忚鍙傛暟锛堜娇鐢ㄩ厤缃腑鐨剆imPhone锛屽鏋滄湭鎻愪緵鍒欎娇鐢ㄩ粯璁ゅ�硷級
-            String simPhone = config.simPhone != null && !config.simPhone.trim().isEmpty() 
-                    ? config.simPhone : "013120122580";
-            h264Encoder.setProtocolParams(simPhone, (byte)1);
-            
-            // 鍒濆鍖栧苟鍚姩锛堜娇鐢ㄩ厤缃腑鐨勫垎杈ㄧ巼锛�
-            // 鏍规嵁cameraId閫夋嫨鎽勫儚澶磋寖鍥�
-            int[] cameraIdRange = DEFAULT_CAMERA_ID_RANGE;
-
-            int[] resolution = {width, height};
-            if (h264Encoder.initialize(cameraIdRange, null, resolution, false)) {
-                // 搴旂敤宸蹭繚瀛樼殑姘村嵃淇℃伅锛堝鏋滄湁锛�
-                if (currentWatermarkInfo != null) {
-                    h264Encoder.setWatermarkInfo(currentWatermarkInfo);
-                    Timber.d("Applied saved watermark info to encoder");
+                Timber.d("Encode started successfully, fileOutput: %b, networkTransmit: %b, resolution: %dx%d, framerate: %d", 
+                        config.enableFileOutput, config.enableNetworkTransmit, width, height, framerate);
+                if (config.enableNetworkTransmit) {
+                    Timber.d("Network server: %s:%d", config.ip, config.port);
                 }
-                h264Encoder.start();
-                Timber.d("Network encode started successfully, server: %s:%d, resolution: %dx%d, framerate: %d", 
-                        config.ip, config.port, width, height, framerate);
                 return 0; // 鎴愬姛
             } else {
                 Timber.e("Failed to initialize encoder");
@@ -498,7 +497,7 @@
                 return 1; // 澶辫触
             }
         } catch (Exception e) {
-            Timber.e(e, "Failed to start network encode");
+            Timber.e(e, "Failed to start encode");
             h264Encoder = null;
             return 1; // 澶辫触
         }
@@ -581,8 +580,8 @@
             h264FileTransmitter.setOnTransmitProgressCallback(new H264FileTransmitter.OnTransmitProgressCallback() {
                 @Override
                 public void onProgress(int currentFrame, int totalFrames) {
-                    Timber.d("File transmit progress: frame %d%s", currentFrame, 
-                            totalFrames > 0 ? " of " + totalFrames : "");
+//                    Timber.d("File transmit progress: frame %d%s", currentFrame,
+//                            totalFrames > 0 ? " of " + totalFrames : "");
                 }
                 
                 @Override
diff --git a/app/src/main/java/com/anyun/h264/H264Encoder.java b/app/src/main/java/com/anyun/h264/H264Encoder.java
index 7c187ad..59525d2 100644
--- a/app/src/main/java/com/anyun/h264/H264Encoder.java
+++ b/app/src/main/java/com/anyun/h264/H264Encoder.java
@@ -173,6 +173,18 @@
     public void setEnableNetworkTransmission(boolean enable) {
         this.enableNetworkTransmission = enable;
         Timber.d("Network transmission " + (enable ? "enabled" : "disabled"));
+
+        // 濡傛灉鍦ㄧ紪鐮佽繃绋嬩腑鍔ㄦ�佸紑鍚綉缁滀紶杈擄紝闇�瑕佺‘淇濆簳灞係ocket宸茬粡寤虹珛
+        if (enable) {
+            if (!protocolHelper.initializeSocket()) {
+                Timber.e("Failed to initialize socket when enabling network transmission");
+            }
+        } else {
+            // 鍔ㄦ�佸叧闂綉缁滀紶杈撴椂锛屽強鏃堕噴鏀惧簳灞係ocket璧勬簮
+            if (protocolHelper != null) {
+                protocolHelper.closeSocket();
+            }
+        }
     }
 
     /**
diff --git a/app/src/main/java/com/anyun/h264/JT1076ProtocolHelper.java b/app/src/main/java/com/anyun/h264/JT1076ProtocolHelper.java
index c438f89..aa7e565 100644
--- a/app/src/main/java/com/anyun/h264/JT1076ProtocolHelper.java
+++ b/app/src/main/java/com/anyun/h264/JT1076ProtocolHelper.java
@@ -55,6 +55,8 @@
     
     // TCP鍙傛暟
     private JT1076TcpClient tcpClient;
+    // 鎺у埗鏈繛鎺ユ棩蹇楃殑杈撳嚭棰戠巼锛岄伩鍏嶅埛灞�
+    private boolean tcpNotConnectedLogged = false;
     
     // RTP鍗忚鍙傛暟
     private String simCardNumber = "123456789012"; // 12浣峉IM鍗″彿
@@ -162,6 +164,8 @@
                     @Override
                     public void onConnected() {
                         Timber.d("TCP connection established");
+                        // 杩炴帴鎴愬姛鍚庯紝鍏佽涓嬫鏂紑鏃跺啀娆℃墦鍗版湭杩炴帴鍛婅
+                        tcpNotConnectedLogged = false;
                     }
                     
                     @Override
@@ -255,8 +259,14 @@
     public void sendTcpPacket(byte[] packet) {
         if (tcpClient != null && tcpClient.isConnected()) {
             tcpClient.sendPacket(packet);
+            // 鍙戦�佹垚鍔燂紝閲嶇疆鏈繛鎺ユ棩蹇楁爣璁�
+            tcpNotConnectedLogged = false;
         } else {
-            Timber.w("TCP socket not connected");
+            // 浠呭湪绗竴娆℃娴嬪埌鏈繛鎺ユ椂鎵撳嵃warn锛岄伩鍏嶆棩蹇楀埛灞�
+            if (!tcpNotConnectedLogged) {
+                Timber.w("TCP socket not connected");
+                tcpNotConnectedLogged = true;
+            }
         }
     }
     

--
Gitblit v1.8.0