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