From 01f07011ee45d99e8b5f64824a5399b597b23be9 Mon Sep 17 00:00:00 2001
From: Dana <Dana_Lee1016@126.com>
Date: 星期二, 27 一月 2026 14:13:27 +0800
Subject: [PATCH] 1.usb rgba 2 ,正常颜色 2:使用帧索引计算时间戳,假设固定帧率。实际采集帧率可能不同,导致时间戳不准确 解决方案:使用实际经过的时间计算时间戳,确保时间戳与实际时间一致
---
app/build.gradle.kts | 38 +++
app/build/generated/aidl_source_output_dir/debug/out/com/safeluck/floatwindow/IMyCallback.java | 2
key/key.jks | 0
app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at | 0
usbcameralib/build.gradle | 6
app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.values.at | 0
key/Verify.txt | 41 ++++
app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab | 0
app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.values.at | 0
app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.values.at | 0
app/build/intermediates/desugar_graph/debug/dexBuilderDebug/out/currentProject/dirs_bucket_9/graph.bin | 0
app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab | 0
app/src/main/java/com/safeluck/floatwindow/manager/AndroidCameraRecordManager.java | 18 +
app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream | 0
app/src/main/java/com/safeluck/floatwindow/manager/UsbCameraRecordManager.java | 105 ++++++++--
key/keysc626.jks | 0
key/keyrk3288.jks | 0
app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab | 0
app/src/main/java/com/safeluck/floatwindow/MediaArgu.java | 1
app/build/generated/aidl_source_output_dir/debug/out/com/safeluck/floatwindow/IMediaAidlInterface.java | 2
app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.len | 0
app/src/main/AndroidManifest.xml | 6
app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i | 0
app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab.values.at | 0
app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.values.at | 0
app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab | 0
app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/counters.tab | 2
app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab | 0
app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream.len | 0
app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab | 0
app/src/main/java/com/safeluck/floatwindow/util/VideoFileUtils.java | 3
app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.values.at | 0
key/bjkey.jks | 0
app/src/main/java/com/safeluck/floatwindow/MainActivity.kt | 368 ++++++++++++++++++++++++++++++++++--
key/key.jks.ori | 0
app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab | 0
key/keysc200.jks | 0
keystore.properties | 4
38 files changed, 540 insertions(+), 56 deletions(-)
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 9ee7366..ff8e19d 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -1,3 +1,6 @@
+import java.io.FileInputStream
+import java.util.Properties
+
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
@@ -7,7 +10,9 @@
android {
namespace = "com.safeluck.floatwindow"
compileSdk = 35
-
+ val keystorePropertiesFile = rootProject.file("keystore.properties")
+ val keystoreProperties = Properties()
+ keystoreProperties.load(FileInputStream(keystorePropertiesFile))
defaultConfig {
applicationId = "com.safeluck.floatwindow"
minSdk = 24
@@ -16,9 +21,27 @@
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
+
+ ndk {
+ abiFilters += listOf("arm64-v8a", "armeabi-v7a")
+ }
}
buildFeatures{
aidl =true
+ }
+ signingConfigs {
+ create("release") {
+ keyPassword = keystoreProperties.getProperty("keyPassword")
+ keyAlias = keystoreProperties.getProperty("keyAlias")
+ storeFile = file(keystoreProperties.getProperty("storeFile") ?: "")
+ storePassword = keystoreProperties.getProperty("storePassword")
+ }
+ getByName("debug") {
+ keyPassword = keystoreProperties.getProperty("keyPassword")
+ keyAlias = keystoreProperties.getProperty("keyAlias")
+ storeFile = file(keystoreProperties.getProperty("storeFile") ?: "")
+ storePassword = keystoreProperties.getProperty("storePassword")
+ }
}
buildTypes {
release {
@@ -27,6 +50,10 @@
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
+ signingConfig = signingConfigs.getByName("release")
+ }
+ debug {
+ signingConfig = signingConfigs.getByName("debug")
}
}
compileOptions {
@@ -39,6 +66,15 @@
buildFeatures {
compose = true
}
+
+ packaging {
+ jniLibs {
+ useLegacyPackaging = false
+ }
+ resources {
+ excludes += "/META-INF/{AL2.0,LGPL2.1}"
+ }
+ }
}
dependencies {
diff --git a/app/build/generated/aidl_source_output_dir/debug/out/com/safeluck/floatwindow/IMediaAidlInterface.java b/app/build/generated/aidl_source_output_dir/debug/out/com/safeluck/floatwindow/IMediaAidlInterface.java
index e24d126..5c6b6e0 100644
--- a/app/build/generated/aidl_source_output_dir/debug/out/com/safeluck/floatwindow/IMediaAidlInterface.java
+++ b/app/build/generated/aidl_source_output_dir/debug/out/com/safeluck/floatwindow/IMediaAidlInterface.java
@@ -1,6 +1,6 @@
/*
* This file is auto-generated. DO NOT MODIFY.
- * Using: D:\Program\ Files\Android\Sdk\build-tools\35.0.0\aidl.exe -pD:\Program\ Files\Android\Sdk\platforms\android-35\framework.aidl -oD:\JetBrainsProjects\AndroidProject\anyunVideo\app\build\generated\aidl_source_output_dir\debug\out -ID:\JetBrainsProjects\AndroidProject\anyunVideo\app\src\main\aidl -ID:\JetBrainsProjects\AndroidProject\anyunVideo\app\src\debug\aidl -ID:\data\.gradle\caches\8.10.2\transforms\53a750d70626c759bd7a6dbaf50185ee\transformed\core-1.12.0\aidl -ID:\data\.gradle\caches\8.10.2\transforms\dc945394860d4e1c7d02ff0c8d3e2e6f\transformed\versionedparcelable-1.1.1\aidl -dC:\Users\Dana\AppData\Local\Temp\aidl14282392422309074909.d D:\JetBrainsProjects\AndroidProject\anyunVideo\app\src\main\aidl\com\safeluck\floatwindow\IMediaAidlInterface.aidl
+ * Using: D:\Program\ Files\Android\Sdk\build-tools\35.0.0\aidl.exe -pD:\Program\ Files\Android\Sdk\platforms\android-35\framework.aidl -oD:\JetBrainsProjects\AndroidProject\anyunVideo\app\build\generated\aidl_source_output_dir\debug\out -ID:\JetBrainsProjects\AndroidProject\anyunVideo\app\src\main\aidl -ID:\JetBrainsProjects\AndroidProject\anyunVideo\app\src\debug\aidl -ID:\data\.gradle\caches\8.10.2\transforms\53a750d70626c759bd7a6dbaf50185ee\transformed\core-1.12.0\aidl -ID:\data\.gradle\caches\8.10.2\transforms\dc945394860d4e1c7d02ff0c8d3e2e6f\transformed\versionedparcelable-1.1.1\aidl -dC:\Users\Dana\AppData\Local\Temp\aidl10441886692587460682.d D:\JetBrainsProjects\AndroidProject\anyunVideo\app\src\main\aidl\com\safeluck\floatwindow\IMediaAidlInterface.aidl
*/
package com.safeluck.floatwindow;
// Declare any non-default types here with import statements
diff --git a/app/build/generated/aidl_source_output_dir/debug/out/com/safeluck/floatwindow/IMyCallback.java b/app/build/generated/aidl_source_output_dir/debug/out/com/safeluck/floatwindow/IMyCallback.java
index db127f2..8b52912 100644
--- a/app/build/generated/aidl_source_output_dir/debug/out/com/safeluck/floatwindow/IMyCallback.java
+++ b/app/build/generated/aidl_source_output_dir/debug/out/com/safeluck/floatwindow/IMyCallback.java
@@ -1,6 +1,6 @@
/*
* This file is auto-generated. DO NOT MODIFY.
- * Using: D:\Program\ Files\Android\Sdk\build-tools\35.0.0\aidl.exe -pD:\Program\ Files\Android\Sdk\platforms\android-35\framework.aidl -oD:\JetBrainsProjects\AndroidProject\anyunVideo\app\build\generated\aidl_source_output_dir\debug\out -ID:\JetBrainsProjects\AndroidProject\anyunVideo\app\src\main\aidl -ID:\JetBrainsProjects\AndroidProject\anyunVideo\app\src\debug\aidl -ID:\data\.gradle\caches\8.10.2\transforms\53a750d70626c759bd7a6dbaf50185ee\transformed\core-1.12.0\aidl -ID:\data\.gradle\caches\8.10.2\transforms\dc945394860d4e1c7d02ff0c8d3e2e6f\transformed\versionedparcelable-1.1.1\aidl -dC:\Users\Dana\AppData\Local\Temp\aidl6375257616930721574.d D:\JetBrainsProjects\AndroidProject\anyunVideo\app\src\main\aidl\com\safeluck\floatwindow\IMyCallback.aidl
+ * Using: D:\Program\ Files\Android\Sdk\build-tools\35.0.0\aidl.exe -pD:\Program\ Files\Android\Sdk\platforms\android-35\framework.aidl -oD:\JetBrainsProjects\AndroidProject\anyunVideo\app\build\generated\aidl_source_output_dir\debug\out -ID:\JetBrainsProjects\AndroidProject\anyunVideo\app\src\main\aidl -ID:\JetBrainsProjects\AndroidProject\anyunVideo\app\src\debug\aidl -ID:\data\.gradle\caches\8.10.2\transforms\53a750d70626c759bd7a6dbaf50185ee\transformed\core-1.12.0\aidl -ID:\data\.gradle\caches\8.10.2\transforms\dc945394860d4e1c7d02ff0c8d3e2e6f\transformed\versionedparcelable-1.1.1\aidl -dC:\Users\Dana\AppData\Local\Temp\aidl6260459078460591487.d D:\JetBrainsProjects\AndroidProject\anyunVideo\app\src\main\aidl\com\safeluck\floatwindow\IMyCallback.aidl
*/
package com.safeluck.floatwindow;
/**
diff --git a/app/build/intermediates/desugar_graph/debug/dexBuilderDebug/out/currentProject/dirs_bucket_9/graph.bin b/app/build/intermediates/desugar_graph/debug/dexBuilderDebug/out/currentProject/dirs_bucket_9/graph.bin
index 2f3be31..07e41e9 100644
--- a/app/build/intermediates/desugar_graph/debug/dexBuilderDebug/out/currentProject/dirs_bucket_9/graph.bin
+++ b/app/build/intermediates/desugar_graph/debug/dexBuilderDebug/out/currentProject/dirs_bucket_9/graph.bin
Binary files differ
diff --git a/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab b/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab
index bdf584a..a314e47 100644
--- a/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab
+++ b/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab
Binary files differ
diff --git a/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.values.at b/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.values.at
index 53b2d29..fc0e221 100644
--- a/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.values.at
+++ b/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.values.at
Binary files differ
diff --git a/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab b/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab
index bdf584a..c0e915b 100644
--- a/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab
+++ b/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab
Binary files differ
diff --git a/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at b/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at
index e9060a7..dac5c8e 100644
--- a/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at
+++ b/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at
Binary files differ
diff --git a/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab b/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab
index 1a1fdbf..7315934 100644
--- a/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab
+++ b/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab
Binary files differ
diff --git a/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab.values.at b/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab.values.at
index 1d49f50..960edd7 100644
--- a/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab.values.at
+++ b/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab.values.at
Binary files differ
diff --git a/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab b/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab
index bdf584a..255bbf4 100644
--- a/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab
+++ b/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab
Binary files differ
diff --git a/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.values.at b/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.values.at
index 1429ce6..5f42412 100644
--- a/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.values.at
+++ b/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.values.at
Binary files differ
diff --git a/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab b/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab
index bdf584a..0feea10 100644
--- a/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab
+++ b/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab
Binary files differ
diff --git a/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.values.at b/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.values.at
index 51508d6..043908f 100644
--- a/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.values.at
+++ b/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.values.at
Binary files differ
diff --git a/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/counters.tab b/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/counters.tab
index 26d3b09..4a12dea 100644
--- a/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/counters.tab
+++ b/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/counters.tab
@@ -1,2 +1,2 @@
-4
+5
0
\ No newline at end of file
diff --git a/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab b/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab
index 2b3434a..f9463a0 100644
--- a/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab
+++ b/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab
Binary files differ
diff --git a/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.values.at b/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.values.at
index 3e23c2a..f6a4f17 100644
--- a/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.values.at
+++ b/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.values.at
Binary files differ
diff --git a/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab b/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab
index 4b0ca2c..f2aff74 100644
--- a/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab
+++ b/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab
Binary files differ
diff --git a/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream b/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream
index 6e7a926..1dd772c 100644
--- a/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream
+++ b/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream
Binary files differ
diff --git a/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream.len b/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream.len
index eb52963..62f3e6f 100644
--- a/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream.len
+++ b/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream.len
Binary files differ
diff --git a/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.len b/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.len
index 93a595b..ec8f944 100644
--- a/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.len
+++ b/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.len
Binary files differ
diff --git a/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.values.at b/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.values.at
index 42c4888..d073f36 100644
--- a/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.values.at
+++ b/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.values.at
Binary files differ
diff --git a/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i b/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i
index 6936967..e6ff6ac 100644
--- a/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i
+++ b/app/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i
Binary files differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index c7e748d..fbd24eb 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,10 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools">
+ android:sharedUserId="android.uid.system"
+ xmlns:tools="http://schemas.android.com/tools"
+ >
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
-
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
android:allowBackup="true"
android:name=".H264Application"
diff --git a/app/src/main/java/com/safeluck/floatwindow/MainActivity.kt b/app/src/main/java/com/safeluck/floatwindow/MainActivity.kt
index fe38740..5d7335d 100644
--- a/app/src/main/java/com/safeluck/floatwindow/MainActivity.kt
+++ b/app/src/main/java/com/safeluck/floatwindow/MainActivity.kt
@@ -1,47 +1,363 @@
package com.safeluck.floatwindow
+import android.content.ComponentName
+import android.content.Context
+import android.content.Intent
+import android.content.ServiceConnection
import android.os.Bundle
+import android.os.IBinder
+import android.os.RemoteException
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
-import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.foundation.layout.padding
-import androidx.compose.material3.Scaffold
-import androidx.compose.material3.Text
-import androidx.compose.runtime.Composable
+import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.rememberScrollState
+import androidx.compose.foundation.verticalScroll
+import androidx.compose.material3.*
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.*
+import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
import com.safeluck.floatwindow.ui.theme.AnyunVideoTheme
+import timber.log.Timber
class MainActivity : ComponentActivity() {
+ private var mediaAidlInterface: IMediaAidlInterface? = null
+ private var serviceConnection: ServiceConnection? = null
+ private var isServiceBound = false
+ private val isServiceBoundState = mutableStateOf(false)
+
+ private val callback = object : IMyCallback.Stub() {
+ @Throws(RemoteException::class)
+ override fun onResult(re: ResponseVO?) {
+ re?.let {
+ Timber.d("Callback received: type=${it.type}, errCode=${it.errCode}, message=${it.message}")
+ }
+ }
+ }
+
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
+
+ serviceConnection = object : ServiceConnection {
+ override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
+ mediaAidlInterface = IMediaAidlInterface.Stub.asInterface(service)
+ isServiceBound = true
+ isServiceBoundState.value = true
+ Timber.d("FloatingService connected")
+ }
+
+ override fun onServiceDisconnected(name: ComponentName?) {
+ mediaAidlInterface = null
+ isServiceBound = false
+ isServiceBoundState.value = false
+ Timber.d("FloatingService disconnected")
+ }
+ }
+
setContent {
AnyunVideoTheme {
- Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
- Greeting(
- name = "Android",
- modifier = Modifier.padding(innerPadding)
+ Surface(
+ modifier = Modifier.fillMaxSize(),
+ color = MaterialTheme.colorScheme.background
+ ) {
+ MainScreen(
+ isServiceBound = isServiceBoundState.value,
+ onBindService = {
+ if (!isServiceBoundState.value && serviceConnection != null) {
+ val intent = Intent(this@MainActivity, FloatingService::class.java)
+ bindService(intent, serviceConnection!!, Context.BIND_AUTO_CREATE)
+ Timber.d("Binding FloatingService")
+ }
+ },
+ onUnbindService = {
+ unbindServiceInternal()
+ },
+ onStartAndroidRecord = { startAndroidRecord() },
+ onStopAndroidRecord = { stopAndroidRecord() },
+ onStartUsbRecord = { startUsbRecord() },
+ onStopUsbRecord = { stopUsbRecord() },
+ onStartUsbPush = { startUsbPush() },
+ onStopUsbPush = { stopUsbPush() }
)
}
}
}
}
-}
-
-@Composable
-fun Greeting(name: String, modifier: Modifier = Modifier) {
- Text(
- text = "Hello $name!",
- modifier = modifier
- )
-}
-
-@Preview(showBackground = true)
-@Composable
-fun GreetingPreview() {
- AnyunVideoTheme {
- Greeting("Android")
+
+ private fun startAndroidRecord() {
+ if (mediaAidlInterface == null) {
+ Timber.w("Service not bound, cannot start Android record")
+ return
+ }
+
+ try {
+ val mediaArgu = MediaArgu().apply {
+ isPush = false
+ isUsedOutCamera = false // Android 鍐呯疆鎽勫儚澶�
+ codeRate = 0
+ frameRate = 0
+ m_screen = MediaArgu.ScreenSolution(640, 480) // 榛樿鍒嗚鲸鐜�
+ recordTime = 0
+ tfCardFlag = 0 // 鍐呴儴瀛樺偍
+ }
+
+ mediaAidlInterface?.registerCallback(callback)
+ mediaAidlInterface?.startMedia(mediaArgu)
+ Timber.d("Started Android camera record")
+ } catch (e: RemoteException) {
+ Timber.e(e, "Error starting Android record")
+ }
}
-}
\ No newline at end of file
+
+ private fun stopAndroidRecord() {
+ if (mediaAidlInterface == null) {
+ Timber.w("Service not bound, cannot stop Android record")
+ return
+ }
+
+ try {
+ mediaAidlInterface?.stopMedia()
+ Timber.d("Stopped Android camera record")
+ } catch (e: RemoteException) {
+ Timber.e(e, "Error stopping Android record")
+ }
+ }
+
+ private fun startUsbRecord() {
+ if (mediaAidlInterface == null) {
+ Timber.w("Service not bound, cannot start USB record")
+ return
+ }
+
+ try {
+ val mediaArgu = MediaArgu().apply {
+ isPush = false
+ isUsedOutCamera = true // USB 鎽勫儚澶�
+ codeRate = 0
+ frameRate = 0
+ m_screen = MediaArgu.ScreenSolution(640, 480) // 榛樿鍒嗚鲸鐜�
+ recordTime = 0
+ tfCardFlag = 0 // 鍐呴儴瀛樺偍
+ }
+
+ mediaAidlInterface?.registerCallback(callback)
+ mediaAidlInterface?.startMedia(mediaArgu)
+ Timber.d("Started USB camera record")
+ } catch (e: RemoteException) {
+ Timber.e(e, "Error starting USB record")
+ }
+ }
+
+ private fun stopUsbRecord() {
+ if (mediaAidlInterface == null) {
+ Timber.w("Service not bound, cannot stop USB record")
+ return
+ }
+
+ try {
+ mediaAidlInterface?.stopMedia()
+ Timber.d("Stopped USB camera record")
+ } catch (e: RemoteException) {
+ Timber.e(e, "Error stopping USB record")
+ }
+ }
+
+ private fun startUsbPush() {
+ if (mediaAidlInterface == null) {
+ Timber.w("Service not bound, cannot start USB push")
+ return
+ }
+
+ try {
+ val mediaArgu = MediaArgu().apply {
+ isPush = true
+ isUsedOutCamera = true // USB 鎽勫儚澶�
+ codeRate = 0
+ frameRate = 0
+ m_screen = MediaArgu.ScreenSolution(640, 480) // 榛樿鍒嗚鲸鐜�
+ url = "rtmp://your-push-url" // TODO: 闇�瑕佽缃疄闄呯殑鎺ㄦ祦鍦板潃
+ userName = ""
+ pwd = ""
+ }
+
+ mediaAidlInterface?.registerCallback(callback)
+ mediaAidlInterface?.startMedia(mediaArgu)
+ Timber.d("Started USB camera push")
+ } catch (e: RemoteException) {
+ Timber.e(e, "Error starting USB push")
+ }
+ }
+
+ private fun stopUsbPush() {
+ if (mediaAidlInterface == null) {
+ Timber.w("Service not bound, cannot stop USB push")
+ return
+ }
+
+ try {
+ mediaAidlInterface?.stopMedia()
+ Timber.d("Stopped USB camera push")
+ } catch (e: RemoteException) {
+ Timber.e(e, "Error stopping USB push")
+ }
+ }
+
+ private fun unbindServiceInternal() {
+ if (isServiceBound && serviceConnection != null) {
+ try {
+ mediaAidlInterface?.unregisterCallback(callback)
+ } catch (e: RemoteException) {
+ Timber.e(e, "Error unregistering callback")
+ }
+ try {
+ unbindService(serviceConnection!!)
+ Timber.d("Unbinding FloatingService")
+ } catch (e: Exception) {
+ Timber.e(e, "Error unbinding service")
+ }
+ isServiceBound = false
+ isServiceBoundState.value = false
+ mediaAidlInterface = null
+ }
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ unbindServiceInternal()
+ }
+}
+
+@Composable
+fun MainScreen(
+ isServiceBound: Boolean,
+ onBindService: () -> Unit,
+ onUnbindService: () -> Unit,
+ onStartAndroidRecord: () -> Unit,
+ onStopAndroidRecord: () -> Unit,
+ onStartUsbRecord: () -> Unit,
+ onStopUsbRecord: () -> Unit,
+ onStartUsbPush: () -> Unit,
+ onStopUsbPush: () -> Unit
+) {
+ Column(
+ modifier = Modifier.fillMaxSize()
+ ) {
+ // 鍥哄畾椤堕儴锛氭爣棰樺拰鐘舵��
+ Column(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(16.dp),
+ horizontalAlignment = Alignment.CenterHorizontally
+ ) {
+ Text(
+ text = "FloatingService 鎺у埗",
+ style = MaterialTheme.typography.headlineMedium,
+ modifier = Modifier.padding(bottom = 8.dp)
+ )
+
+ Text(
+ text = if (isServiceBound) "鏈嶅姟鐘舵��: 宸茬粦瀹�" else "鏈嶅姟鐘舵��: 鏈粦瀹�",
+ style = MaterialTheme.typography.bodyMedium,
+ color = if (isServiceBound) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.error,
+ modifier = Modifier.padding(bottom = 16.dp)
+ )
+ }
+
+ Divider()
+
+ // 鍙粴鍔ㄧ殑鎸夐挳鍒楄〃
+ Column(
+ modifier = Modifier
+ .fillMaxSize()
+ .verticalScroll(rememberScrollState())
+ .padding(horizontal = 16.dp),
+ horizontalAlignment = Alignment.CenterHorizontally,
+ verticalArrangement = Arrangement.spacedBy(12.dp)
+ ) {
+ Spacer(modifier = Modifier.height(12.dp))
+
+ // 鎸夐挳 1: 缁戝畾鏈嶅姟
+ Button(
+ onClick = onBindService,
+ modifier = Modifier.fillMaxWidth(),
+ enabled = !isServiceBound
+ ) {
+ Text("1. 缁戝畾 FloatingService")
+ }
+
+ // 鎸夐挳 2: 瑙g粦鏈嶅姟
+ Button(
+ onClick = onUnbindService,
+ modifier = Modifier.fillMaxWidth(),
+ enabled = isServiceBound
+ ) {
+ Text("2. 瑙g粦 FloatingService")
+ }
+
+ Divider(modifier = Modifier.padding(vertical = 8.dp))
+
+ // 鎸夐挳 3: 寮�濮� Android 鐩告満褰曞儚
+ Button(
+ onClick = onStartAndroidRecord,
+ modifier = Modifier.fillMaxWidth(),
+ enabled = isServiceBound
+ ) {
+ Text("3. 寮�濮� Android 鐩告満褰曞儚")
+ }
+
+ // 鎸夐挳 4: 缁撴潫 Android 鐩告満褰曞儚
+ Button(
+ onClick = onStopAndroidRecord,
+ modifier = Modifier.fillMaxWidth(),
+ enabled = isServiceBound
+ ) {
+ Text("4. 缁撴潫 Android 鐩告満褰曞儚")
+ }
+
+ Divider(modifier = Modifier.padding(vertical = 8.dp))
+
+ // 鎸夐挳 5: 寮�濮� USB 鐩告満褰曞儚
+ Button(
+ onClick = onStartUsbRecord,
+ modifier = Modifier.fillMaxWidth(),
+ enabled = isServiceBound
+ ) {
+ Text("5. 寮�濮� USB 鐩告満褰曞儚")
+ }
+
+ // 鎸夐挳 6: 缁撴潫 USB 鐩告満褰曞儚
+ Button(
+ onClick = onStopUsbRecord,
+ modifier = Modifier.fillMaxWidth(),
+ enabled = isServiceBound
+ ) {
+ Text("6. 缁撴潫 USB 鐩告満褰曞儚")
+ }
+
+ Divider(modifier = Modifier.padding(vertical = 8.dp))
+
+ // 鎸夐挳 7: 寮�濮� USB 鎺ㄦ祦
+ Button(
+ onClick = onStartUsbPush,
+ modifier = Modifier.fillMaxWidth(),
+ enabled = isServiceBound
+ ) {
+ Text("7. 寮�濮� USB 鎺ㄦ祦")
+ }
+
+ // 鎸夐挳 8: 缁撴潫 USB 鎺ㄦ祦
+ Button(
+ onClick = onStopUsbPush,
+ modifier = Modifier.fillMaxWidth(),
+ enabled = isServiceBound
+ ) {
+ Text("8. 缁撴潫 USB 鎺ㄦ祦")
+ }
+
+ Spacer(modifier = Modifier.height(12.dp))
+ }
+ }
+}
diff --git a/app/src/main/java/com/safeluck/floatwindow/MediaArgu.java b/app/src/main/java/com/safeluck/floatwindow/MediaArgu.java
index 4d8ebb1..dff6790 100644
--- a/app/src/main/java/com/safeluck/floatwindow/MediaArgu.java
+++ b/app/src/main/java/com/safeluck/floatwindow/MediaArgu.java
@@ -107,6 +107,7 @@
this.pwd = pwd;
}
+
public static class ScreenSolution implements Parcelable {
int width;
int height;
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 98f6fc6..a625b59 100644
--- a/app/src/main/java/com/safeluck/floatwindow/manager/AndroidCameraRecordManager.java
+++ b/app/src/main/java/com/safeluck/floatwindow/manager/AndroidCameraRecordManager.java
@@ -186,15 +186,31 @@
}
// 璁剧疆MediaRecorder
+ // 娉ㄦ剰锛歁ediaRecorder鐨勮缃『搴忛潪甯搁噸瑕侊紝蹇呴』涓ユ牸鎸夌収浠ヤ笅椤哄簭锛�
mediaRecorder = new MediaRecorder();
+
+ // 1. 璁剧疆鏁版嵁婧愶紙蹇呴』鍦╯etOutputFormat涔嬪墠锛�
+ mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
+
+ // 2. 璁剧疆杈撳嚭鏍煎紡锛堝繀椤诲湪setOutputFile鍜岀紪鐮佸櫒涔嬪墠锛�
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
+
+ // 3. 璁剧疆杈撳嚭鏂囦欢锛堝繀椤诲湪缂栫爜鍣ㄤ箣鍓嶏級
mediaRecorder.setOutputFile(currentVideoFile.getAbsolutePath());
+
+ // 4. 璁剧疆缂栫爜鍣紙蹇呴』鍦╯etOutputFormat涔嬪悗锛�
+ mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
+ mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
+
+ // 5. 璁剧疆缂栫爜鍙傛暟锛堝繀椤诲湪缂栫爜鍣ㄤ箣鍚庯級
+ mediaRecorder.setAudioEncodingBitRate(64000); // 64kbps
+ mediaRecorder.setAudioSamplingRate(44100); // 44.1kHz
mediaRecorder.setVideoEncodingBitRate(width * height * 3);
mediaRecorder.setVideoFrameRate(20);
mediaRecorder.setVideoSize(width, height);
- mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
+ // 6. 鍑嗗MediaRecorder
mediaRecorder.prepare();
// 鍒涘缓Surface
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..1047097 100644
--- a/app/src/main/java/com/safeluck/floatwindow/manager/UsbCameraRecordManager.java
+++ b/app/src/main/java/com/safeluck/floatwindow/manager/UsbCameraRecordManager.java
@@ -70,6 +70,9 @@
private File currentVideoFile;
private long currentFileStartTime;
+ // 褰曞埗寮�濮嬫椂闂达紙绾崇锛夛紝鐢ㄤ簬鏃堕棿鎴冲悓姝�
+ private volatile long recordingStartTimeNs = 0;
+
/**
* 褰曞儚鍥炶皟鎺ュ彛
*/
@@ -165,7 +168,7 @@
usbCamera.setenv();
// 浣跨敤prepareCamera鏂规硶锛宑amera_id鑼冨洿[0,9]
- int[] cameraIds = {0, 9};
+ int[] cameraIds = {0, 2};
String cameraName = null; // 涓嶆寚瀹氱壒瀹氬悕绉�
// 濡傛灉杩斿洖闈�0锛屼唬琛ㄦ墦寮�澶辫触锛屽垯鍏坰topCamera鍐嶉噸璇曪紝鏈�澶�3娆�
@@ -366,12 +369,18 @@
Timber.d("闊抽褰曞埗宸插惎鍔�");
}
+ // 娉ㄦ剰锛氫笉瑕佸湪杩欓噷涓诲姩妫�鏌ラ煶棰戠紪鐮佸櫒杈撳嚭鏍煎紡
+ // 鍥犱负 MediaCodec 鐨� getOutputFormat() 鍦ㄧ紪鐮佸櫒鍚姩鍚庡彲鑳借繑鍥� null
+ // 搴旇绛夊緟 INFO_OUTPUT_FORMAT_CHANGED 浜嬩欢
+
// 鍚姩闊抽缂栫爜绾跨▼
audioThread = new AudioThread();
audioThread.start();
Timber.d("寮�濮嬪綍鍍忥紝鍒嗚鲸鐜�: %dx%d", width, height);
+ // 璁板綍寮�濮嬫椂闂达紙绾崇锛岀敤浜庣簿纭椂闂存埑锛�
+ recordingStartTimeNs = System.nanoTime();
long frameCount = 0;
long lastFileChangeTime = System.currentTimeMillis();
@@ -400,6 +409,9 @@
break;
}
+ // 閲嶇疆寮�濮嬫椂闂�
+ recordingStartTimeNs = System.nanoTime();
+
// 閲嶆柊鍚姩闊抽褰曞埗
if (audioRecord != null) {
audioRecord.startRecording();
@@ -426,11 +438,13 @@
}
// 鑾峰彇YUV鏁版嵁 (鍙傛暟0琛ㄧず褰曞儚)
- usbCamera.rgba(0, buffer);
+ usbCamera.rgba(2, buffer);
// 缂栫爜骞跺啓鍏ユ枃浠�
if (videoEncoder != null && mediaMuxer != null) {
- encodeFrame(buffer, frameCount, width, height);
+ // 璁$畻瀹為檯缁忚繃鐨勬椂闂达紙寰锛�
+ long elapsedTimeUs = (System.nanoTime() - recordingStartTimeNs) / 1000;
+ encodeFrame(buffer, elapsedTimeUs, width, height);
frameCount++;
}
@@ -461,8 +475,12 @@
/**
* 缂栫爜涓�甯ф暟鎹�
+ * @param yuvData YUV鏁版嵁
+ * @param presentationTimeUs 鏃堕棿鎴筹紙寰锛夛紝鍩轰簬瀹為檯寮�濮嬫椂闂�
+ * @param width 瀹藉害
+ * @param height 楂樺害
*/
- private void encodeFrame(byte[] yuvData, long frameIndex, int width, int height) {
+ private void encodeFrame(byte[] yuvData, long presentationTimeUs, int width, int height) {
try {
// 鑾峰彇杈撳叆缂撳啿鍖�
int inputBufferIndex = videoEncoder.dequeueInputBuffer(10000);
@@ -472,7 +490,7 @@
inputBuffer.clear();
inputBuffer.put(yuvData);
- long presentationTimeUs = (frameIndex * 1000000) / FRAME_RATE;
+ // 浣跨敤瀹為檯缁忚繃鐨勬椂闂翠綔涓烘椂闂存埑
videoEncoder.queueInputBuffer(inputBufferIndex, 0, yuvData.length,
presentationTimeUs, 0);
}
@@ -482,18 +500,35 @@
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) {
+ // 妫�鏌� muxer 鏄惁宸插惎鍔紝濡傛灉宸插惎鍔ㄥ垯鏃犳硶娣诲姞杞ㄩ亾
+ if (muxerStarted) {
+ Timber.e("Muxer already started, cannot add video track");
+ break;
+ }
+ if (videoTrackIndex < 0) {
+ videoTrackIndex = mediaMuxer.addTrack(newFormat);
+ Timber.d("瑙嗛杞ㄩ亾宸叉坊鍔�: %d", videoTrackIndex);
+ checkAndStartMuxer();
+ }
+ }
+ outputBufferIndex = videoEncoder.dequeueOutputBuffer(bufferInfo, 0);
+ continue;
} else if (outputBufferIndex >= 0) {
ByteBuffer outputBuffer = videoEncoder.getOutputBuffer(outputBufferIndex);
+ // 鍙湁鍦� muxer 宸插惎鍔ㄤ笖杞ㄩ亾绱㈠紩鏈夋晥鏃舵墠鍐欏叆鏁版嵁
if (outputBuffer != null && muxerStarted && videoTrackIndex >= 0) {
outputBuffer.position(bufferInfo.offset);
outputBuffer.limit(bufferInfo.offset + bufferInfo.size);
- mediaMuxer.writeSampleData(videoTrackIndex, outputBuffer, bufferInfo);
+ try {
+ mediaMuxer.writeSampleData(videoTrackIndex, outputBuffer, bufferInfo);
+ } catch (Exception e) {
+ Timber.e(e, "Error writing video sample data");
+ }
}
videoEncoder.releaseOutputBuffer(outputBufferIndex, false);
}
@@ -512,9 +547,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);
}
}
@@ -535,7 +576,7 @@
try {
byte[] audioBuffer = new byte[audioBufferSize];
- long audioFrameCount = 0;
+ long totalSamplesRead = 0; // 鎬婚噰鏍锋暟
while (isRecording && audioRecord != null && audioEncoder != null) {
// 璇诲彇闊抽鏁版嵁
@@ -546,8 +587,8 @@
}
// 缂栫爜闊抽鏁版嵁
- encodeAudio(audioBuffer, readSize, audioFrameCount);
- audioFrameCount += readSize / 2; // 16浣嶉噰鏍凤紝姣忎釜閲囨牱2瀛楄妭
+ encodeAudio(audioBuffer, readSize, totalSamplesRead);
+ totalSamplesRead += readSize / 2; // 16浣嶉噰鏍凤紝姣忎釜閲囨牱2瀛楄妭
}
} catch (Exception e) {
@@ -559,10 +600,13 @@
/**
* 缂栫爜闊抽鏁版嵁
+ * @param audioData 闊抽鏁版嵁
+ * @param size 鏁版嵁澶у皬锛堝瓧鑺傦級
+ * @param totalSamples 鎬婚噰鏍锋暟锛堜粠寮�濮嬪埌鐜板湪鐨勭疮璁¢噰鏍锋暟锛�
*/
- private void encodeAudio(byte[] audioData, int size, long frameCount) {
+ private void encodeAudio(byte[] audioData, int size, long totalSamples) {
try {
- // 鑾峰彇杈撳叆缂撳啿鍖�
+ // 鑾峰彇杈撳叆缂撳啿鍖猴紙鍗充娇 muxer 鏈惎鍔ㄤ篃瑕佺紪鐮侊紝浠ヤ究灏藉揩鑾峰緱杈撳嚭鏍煎紡锛�
int inputBufferIndex = audioEncoder.dequeueInputBuffer(10000);
if (inputBufferIndex >= 0) {
ByteBuffer inputBuffer = audioEncoder.getInputBuffer(inputBufferIndex);
@@ -570,7 +614,9 @@
inputBuffer.clear();
inputBuffer.put(audioData, 0, size);
- long presentationTimeUs = (frameCount * 1000000) / SAMPLE_RATE;
+ // 浣跨敤閲囨牱鏁拌绠楁椂闂存埑锛堝井绉掞級
+ // totalSamples 鏄噰鏍锋暟锛孲AMPLE_RATE 鏄瘡绉掗噰鏍锋暟
+ long presentationTimeUs = (totalSamples * 1000000) / SAMPLE_RATE;
audioEncoder.queueInputBuffer(inputBufferIndex, 0, size,
presentationTimeUs, 0);
}
@@ -580,18 +626,35 @@
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) {
+ // 妫�鏌� muxer 鏄惁宸插惎鍔紝濡傛灉宸插惎鍔ㄥ垯鏃犳硶娣诲姞杞ㄩ亾
+ if (muxerStarted) {
+ Timber.e("Muxer already started, cannot add audio track");
+ break;
+ }
+ if (audioTrackIndex < 0) {
+ audioTrackIndex = mediaMuxer.addTrack(newFormat);
+ Timber.d("闊抽杞ㄩ亾宸叉坊鍔�: %d", audioTrackIndex);
+ checkAndStartMuxer();
+ }
+ }
+ outputBufferIndex = audioEncoder.dequeueOutputBuffer(bufferInfo, 0);
+ continue;
} else if (outputBufferIndex >= 0) {
ByteBuffer outputBuffer = audioEncoder.getOutputBuffer(outputBufferIndex);
+ // 鍙湁鍦� muxer 宸插惎鍔ㄤ笖杞ㄩ亾绱㈠紩鏈夋晥鏃舵墠鍐欏叆鏁版嵁
if (outputBuffer != null && muxerStarted && audioTrackIndex >= 0) {
outputBuffer.position(bufferInfo.offset);
outputBuffer.limit(bufferInfo.offset + bufferInfo.size);
- mediaMuxer.writeSampleData(audioTrackIndex, outputBuffer, bufferInfo);
+ try {
+ mediaMuxer.writeSampleData(audioTrackIndex, outputBuffer, bufferInfo);
+ } catch (Exception e) {
+ Timber.e(e, "Error writing audio sample data");
+ }
}
audioEncoder.releaseOutputBuffer(outputBufferIndex, false);
}
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 c51d1d3..d9b0128 100644
--- a/app/src/main/java/com/safeluck/floatwindow/util/VideoFileUtils.java
+++ b/app/src/main/java/com/safeluck/floatwindow/util/VideoFileUtils.java
@@ -1,6 +1,7 @@
package com.safeluck.floatwindow.util;
import android.content.Context;
+import android.os.Environment;
import timber.log.Timber;
@@ -36,7 +37,7 @@
baseDir = new File(storagePath);
} else {
// 鍐呴儴瀛樺偍
- baseDir = context.getFilesDir();
+ baseDir = Environment.getExternalStorageDirectory();
}
// 鍒涘缓 AnYun_VIDEO 鐩綍
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/key/bjkey.jks b/key/bjkey.jks
new file mode 100644
index 0000000..35abed1
--- /dev/null
+++ b/key/bjkey.jks
Binary files differ
diff --git a/key/key.jks b/key/key.jks
new file mode 100644
index 0000000..7b43d77
--- /dev/null
+++ b/key/key.jks
Binary files differ
diff --git a/key/key.jks.ori b/key/key.jks.ori
new file mode 100644
index 0000000..3908383
--- /dev/null
+++ b/key/key.jks.ori
Binary files differ
diff --git a/key/keyrk3288.jks b/key/keyrk3288.jks
new file mode 100644
index 0000000..2f65bee
--- /dev/null
+++ b/key/keyrk3288.jks
Binary files differ
diff --git a/key/keysc200.jks b/key/keysc200.jks
new file mode 100644
index 0000000..9fd3690
--- /dev/null
+++ b/key/keysc200.jks
Binary files differ
diff --git a/key/keysc626.jks b/key/keysc626.jks
new file mode 100644
index 0000000..bb729ce
--- /dev/null
+++ b/key/keysc626.jks
Binary files differ
diff --git a/keystore.properties b/keystore.properties
new file mode 100644
index 0000000..4504553
--- /dev/null
+++ b/keystore.properties
@@ -0,0 +1,4 @@
+storePassword = 123456
+keyPassword = 123456
+keyAlias = key0
+storeFile = ../key/key.jks
\ 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