From 01d5238738887b1739cede0c6b589b8c4e34031d Mon Sep 17 00:00:00 2001
From: Dana <Dana_Lee1016@126.com>
Date: 星期二, 27 一月 2026 13:06:05 +0800
Subject: [PATCH] 1.usb可以录像,颜色不对

---
 app/build.gradle.kts                                                           |   13 ++++
 usbcameralib/build.gradle                                                      |    6 +
 key/Verify.txt                                                                 |   41 +++++++++++++
 app/src/main/java/com/safeluck/floatwindow/manager/UsbCameraRecordManager.java |   69 ++++++++++++++++++++--
 4 files changed, 120 insertions(+), 9 deletions(-)

diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index a52ee95..ff8e19d 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -21,6 +21,10 @@
         versionName = "1.0"
 
         testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
+        
+        ndk {
+            abiFilters += listOf("arm64-v8a", "armeabi-v7a")
+        }
     }
     buildFeatures{
         aidl =true
@@ -62,6 +66,15 @@
     buildFeatures {
         compose = true
     }
+    
+    packaging {
+        jniLibs {
+            useLegacyPackaging = false
+        }
+        resources {
+            excludes += "/META-INF/{AL2.0,LGPL2.1}"
+        }
+    }
 }
 
 dependencies {
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 d136622..9c1e67c 100644
--- a/app/src/main/java/com/safeluck/floatwindow/manager/UsbCameraRecordManager.java
+++ b/app/src/main/java/com/safeluck/floatwindow/manager/UsbCameraRecordManager.java
@@ -366,6 +366,20 @@
                     Timber.d("闊抽褰曞埗宸插惎鍔�");
                 }
                 
+                // 涓诲姩妫�鏌ラ煶棰戠紪鐮佸櫒杈撳嚭鏍煎紡锛堝彲鑳藉湪澶勭悊鏁版嵁鍓嶅氨鏈夋牸寮忥級
+                try {
+                    MediaFormat audioFormat = audioEncoder.getOutputFormat();
+                    if (audioFormat != null) {
+                        synchronized (UsbCameraRecordManager.this) {
+                            audioTrackIndex = mediaMuxer.addTrack(audioFormat);
+                            Timber.d("闊抽杞ㄩ亾宸叉坊鍔狅紙涓诲姩妫�鏌ワ級: %d", audioTrackIndex);
+                            checkAndStartMuxer();
+                        }
+                    }
+                } catch (Exception e) {
+                    Timber.d("闊抽缂栫爜鍣ㄨ緭鍑烘牸寮忓皻鏈噯澶囧ソ锛屽皢鍦ㄥ鐞嗘暟鎹椂娣诲姞");
+                }
+                
                 // 鍚姩闊抽缂栫爜绾跨▼
                 audioThread = new AudioThread();
                 audioThread.start();
@@ -374,6 +388,8 @@
                 
                 long frameCount = 0;
                 long lastFileChangeTime = System.currentTimeMillis();
+                long audioTrackWaitStartTime = System.currentTimeMillis();
+                final long AUDIO_TRACK_TIMEOUT_MS = 3000; // 3绉掕秴鏃�
                 
                 // 寰幆澶勭悊鎽勫儚澶存暟鎹�
                 while (isRunning && cameraExists) {
@@ -432,6 +448,27 @@
                     if (videoEncoder != null && mediaMuxer != null) {
                         encodeFrame(buffer, frameCount, width, height);
                         frameCount++;
+                        
+                        // 濡傛灉闊抽杞ㄩ亾瓒呮椂鏈噯澶囧ソ锛屽皾璇曚粎鐢ㄨ棰戣建閬撳惎鍔�
+                        if (!muxerStarted && videoTrackIndex >= 0 && audioTrackIndex < 0) {
+                            // 閲嶇敤寰幆涓凡瀹氫箟鐨� currentTime 鍙橀噺
+                            if (currentTime - audioTrackWaitStartTime > AUDIO_TRACK_TIMEOUT_MS) {
+                                Timber.w("闊抽杞ㄩ亾瓒呮椂鏈噯澶囧ソ锛屼粎浣跨敤瑙嗛杞ㄩ亾鍚姩Muxer");
+                                synchronized (UsbCameraRecordManager.this) {
+                                    // 鍒涘缓涓�涓亣鐨勯煶棰戣建閬撶储寮曪紝鎴栬�呯洿鎺ュ惎鍔紙浣哅ediaMuxer瑕佹眰鑷冲皯涓�涓建閬擄級
+                                    // 瀹為檯涓奙ediaMuxer闇�瑕佽嚦灏戜竴涓建閬擄紝鎵�浠ュ鏋滆棰戣建閬撳噯澶囧ソ浜嗗氨鍙互鍚姩
+                                    if (videoTrackIndex >= 0) {
+                                        try {
+                                            mediaMuxer.start();
+                                            muxerStarted = true;
+                                            Timber.d("Muxer started with video track only: %d", videoTrackIndex);
+                                        } catch (Exception e) {
+                                            Timber.e(e, "Failed to start muxer with video only");
+                                        }
+                                    }
+                                }
+                            }
+                        }
                     }
                     
                     // 鎺у埗甯х巼锛岀害20fps
@@ -482,12 +519,17 @@
                 MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
                 int outputBufferIndex = videoEncoder.dequeueOutputBuffer(bufferInfo, 0);
                 
-                while (outputBufferIndex >= 0) {
+                while (outputBufferIndex != MediaCodec.INFO_TRY_AGAIN_LATER) {
                     if (outputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
                         // 杈撳嚭鏍煎紡鏀瑰彉锛屾坊鍔犺棰戣建閬�
                         MediaFormat newFormat = videoEncoder.getOutputFormat();
-                        videoTrackIndex = mediaMuxer.addTrack(newFormat);
-                        checkAndStartMuxer();
+                        synchronized (UsbCameraRecordManager.this) {
+                            videoTrackIndex = mediaMuxer.addTrack(newFormat);
+                            Timber.d("瑙嗛杞ㄩ亾宸叉坊鍔�: %d", videoTrackIndex);
+                            checkAndStartMuxer();
+                        }
+                        outputBufferIndex = videoEncoder.dequeueOutputBuffer(bufferInfo, 0);
+                        continue;
                     } else if (outputBufferIndex >= 0) {
                         ByteBuffer outputBuffer = videoEncoder.getOutputBuffer(outputBufferIndex);
                         if (outputBuffer != null && muxerStarted && videoTrackIndex >= 0) {
@@ -512,9 +554,15 @@
      */
     private synchronized void checkAndStartMuxer() {
         if (!muxerStarted && videoTrackIndex >= 0 && audioTrackIndex >= 0) {
-            mediaMuxer.start();
-            muxerStarted = true;
+            try {
+                mediaMuxer.start();
+                muxerStarted = true;
                 Timber.d("Muxer started, video track: %d, audio track: %d", videoTrackIndex, audioTrackIndex);
+            } catch (Exception e) {
+                Timber.e(e, "Failed to start muxer");
+            }
+        } else {
+            Timber.d("Muxer not started yet, video track: %d, audio track: %d", videoTrackIndex, audioTrackIndex);
         }
     }
     
@@ -580,12 +628,17 @@
                 MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
                 int outputBufferIndex = audioEncoder.dequeueOutputBuffer(bufferInfo, 0);
                 
-                while (outputBufferIndex >= 0) {
+                while (outputBufferIndex != MediaCodec.INFO_TRY_AGAIN_LATER) {
                     if (outputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
                         // 杈撳嚭鏍煎紡鏀瑰彉锛屾坊鍔犻煶棰戣建閬�
                         MediaFormat newFormat = audioEncoder.getOutputFormat();
-                        audioTrackIndex = mediaMuxer.addTrack(newFormat);
-                        checkAndStartMuxer();
+                        synchronized (UsbCameraRecordManager.this) {
+                            audioTrackIndex = mediaMuxer.addTrack(newFormat);
+                            Timber.d("闊抽杞ㄩ亾宸叉坊鍔�: %d", audioTrackIndex);
+                            checkAndStartMuxer();
+                        }
+                        outputBufferIndex = audioEncoder.dequeueOutputBuffer(bufferInfo, 0);
+                        continue;
                     } else if (outputBufferIndex >= 0) {
                         ByteBuffer outputBuffer = audioEncoder.getOutputBuffer(outputBufferIndex);
                         if (outputBuffer != null && muxerStarted && audioTrackIndex >= 0) {
diff --git a/key/Verify.txt b/key/Verify.txt
new file mode 100644
index 0000000..f819a2e
--- /dev/null
+++ b/key/Verify.txt
@@ -0,0 +1,41 @@
+	private static PrivateKey getKey(String key, char[] password) throws Exception {
+		byte[] cabuf = new BASE64Decoder().decodeBuffer(key);
+		KeyStore keyStore = KeyStore.getInstance("PKCS12");
+		keyStore.load(new ByteArrayInputStream(cabuf), password);
+		Enumeration<String> aliases = keyStore.aliases();
+		if (!aliases.hasMoreElements()) {
+			throw new RuntimeException("no alias found");
+		}
+		String alias = aliases.nextElement();
+		PrivateKey privateKey = (RSAPrivateCrtKeyImpl) keyStore.getKey(alias, password);
+		return privateKey;
+	}
+
+	public static String sign(String data, PrivateKey key) throws Exception {
+//		MessageDigest md = MessageDigest.getInstance("SHA-256");
+		MessageDigest md = MessageDigest.getInstance("SHA-1");
+		md.update(data.getBytes("utf-8"));
+		byte[] hash = md.digest();
+//		Cipher cipher = Cipher.getInstance("RSA");
+		Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
+		cipher.init(Cipher.ENCRYPT_MODE, key);
+		byte[] encrypted = cipher.doFinal(hash);
+		return HexBin.encode(encrypted);
+	}
+
+
+	public static String sign(String data, String keyString ,String pwd ) throws Exception {
+		char[] password = pwd.toCharArray();
+
+		return sign(data,getKey(keyString,password));
+	}
+
+
+	public static void main(String[] args) {
+		try{
+			String sign = sign("xuanborobot123456nullnullnull","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","27U777");
+			System.out.println(sign);
+		}catch (Exception e){
+			e.printStackTrace();
+		}
+	}
\ No newline at end of file
diff --git a/usbcameralib/build.gradle b/usbcameralib/build.gradle
index 78d2812..0afac34 100644
--- a/usbcameralib/build.gradle
+++ b/usbcameralib/build.gradle
@@ -16,6 +16,8 @@
             cmake {
                 arguments "-DANDROID_ARM_NEON=TRUE"
                 cppFlags ""
+                // 纭繚浣跨敤 c++_shared STL
+                arguments "-DANDROID_STL=c++_shared"
             }
         }
         ndk {
@@ -43,7 +45,9 @@
         pickFirst 'lib/armeabi-v7a/libturbojpeg.so'
         pickFirst 'lib/arm64-v8a/libjpeg.so'
         pickFirst 'lib/arm64-v8a/libturbojpeg.so'
-
+        // 纭繚 libc++_shared.so 琚寘鍚�
+        pickFirst 'lib/armeabi-v7a/libc++_shared.so'
+        pickFirst 'lib/arm64-v8a/libc++_shared.so'
     }
 
 }

--
Gitblit v1.8.0