diff --git a/app/build.gradle b/app/build.gradle
index 796cfcc..166d246 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -13,6 +13,10 @@
targetSdkVersion 33
versionCode 1000
versionName "1.0.0.0"
+
+ ndk {
+ abiFilters "armeabi-v7a", "arm64-v8a", "x86", "x86_64"
+ }
}
buildTypes {
@@ -98,4 +102,6 @@
implementation 'org.greenrobot:greendao:3.3.0'
//数据库升级
implementation 'io.github.yuweiguocn:GreenDaoUpgradeHelper:v2.2.1'
+ //ffmpeg
+ implementation 'com.github.microshow:RxFFmpeg:4.9.0'
}
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index 796cfcc..166d246 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -13,6 +13,10 @@
targetSdkVersion 33
versionCode 1000
versionName "1.0.0.0"
+
+ ndk {
+ abiFilters "armeabi-v7a", "arm64-v8a", "x86", "x86_64"
+ }
}
buildTypes {
@@ -98,4 +102,6 @@
implementation 'org.greenrobot:greendao:3.3.0'
//数据库升级
implementation 'io.github.yuweiguocn:GreenDaoUpgradeHelper:v2.2.1'
+ //ffmpeg
+ implementation 'com.github.microshow:RxFFmpeg:4.9.0'
}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index b4fb060..6dc1bff 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -38,5 +38,9 @@
android:name=".view.BigImageActivity"
android:screenOrientation="landscape"
android:theme="@style/Theme.BigImageActivity" />
+
+
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index 796cfcc..166d246 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -13,6 +13,10 @@
targetSdkVersion 33
versionCode 1000
versionName "1.0.0.0"
+
+ ndk {
+ abiFilters "armeabi-v7a", "arm64-v8a", "x86", "x86_64"
+ }
}
buildTypes {
@@ -98,4 +102,6 @@
implementation 'org.greenrobot:greendao:3.3.0'
//数据库升级
implementation 'io.github.yuweiguocn:GreenDaoUpgradeHelper:v2.2.1'
+ //ffmpeg
+ implementation 'com.github.microshow:RxFFmpeg:4.9.0'
}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index b4fb060..6dc1bff 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -38,5 +38,9 @@
android:name=".view.BigImageActivity"
android:screenOrientation="landscape"
android:theme="@style/Theme.BigImageActivity" />
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt b/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt
index 9643a69..6f48798 100644
--- a/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt
+++ b/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt
@@ -35,7 +35,9 @@
//根据不同的日期显示不同的改日期下的九宫格形式子文件
val videoDir = File(context.getExternalFilesDir(Environment.DIRECTORY_MOVIES), date)
videoDir.listFiles()?.forEach {
- fileBeans.add(it)
+ if (it.name.startsWith("t")) {
+ fileBeans.add(it)
+ }
}
val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), date)
diff --git a/app/build.gradle b/app/build.gradle
index 796cfcc..166d246 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -13,6 +13,10 @@
targetSdkVersion 33
versionCode 1000
versionName "1.0.0.0"
+
+ ndk {
+ abiFilters "armeabi-v7a", "arm64-v8a", "x86", "x86_64"
+ }
}
buildTypes {
@@ -98,4 +102,6 @@
implementation 'org.greenrobot:greendao:3.3.0'
//数据库升级
implementation 'io.github.yuweiguocn:GreenDaoUpgradeHelper:v2.2.1'
+ //ffmpeg
+ implementation 'com.github.microshow:RxFFmpeg:4.9.0'
}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index b4fb060..6dc1bff 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -38,5 +38,9 @@
android:name=".view.BigImageActivity"
android:screenOrientation="landscape"
android:theme="@style/Theme.BigImageActivity" />
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt b/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt
index 9643a69..6f48798 100644
--- a/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt
+++ b/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt
@@ -35,7 +35,9 @@
//根据不同的日期显示不同的改日期下的九宫格形式子文件
val videoDir = File(context.getExternalFilesDir(Environment.DIRECTORY_MOVIES), date)
videoDir.listFiles()?.forEach {
- fileBeans.add(it)
+ if (it.name.startsWith("t")) {
+ fileBeans.add(it)
+ }
}
val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), date)
diff --git a/app/src/main/java/com/casic/endoscope/base/BaseApplication.kt b/app/src/main/java/com/casic/endoscope/base/BaseApplication.kt
index 6439217..21cc4f5 100644
--- a/app/src/main/java/com/casic/endoscope/base/BaseApplication.kt
+++ b/app/src/main/java/com/casic/endoscope/base/BaseApplication.kt
@@ -5,6 +5,7 @@
import com.casic.endoscope.greendao.DaoSession
import com.casic.endoscope.utils.EndoscopeDevOpenHelper
import com.pengxh.kt.lite.utils.SaveKeyValues
+import io.microshow.rxffmpeg.RxFFmpegInvoke
import kotlin.properties.Delegates
class BaseApplication : Application() {
@@ -24,6 +25,7 @@
application = this
SaveKeyValues.initSharedPreferences(this)
initDataBase()
+ RxFFmpegInvoke.getInstance().setDebug(false)
}
private fun initDataBase() {
diff --git a/app/build.gradle b/app/build.gradle
index 796cfcc..166d246 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -13,6 +13,10 @@
targetSdkVersion 33
versionCode 1000
versionName "1.0.0.0"
+
+ ndk {
+ abiFilters "armeabi-v7a", "arm64-v8a", "x86", "x86_64"
+ }
}
buildTypes {
@@ -98,4 +102,6 @@
implementation 'org.greenrobot:greendao:3.3.0'
//数据库升级
implementation 'io.github.yuweiguocn:GreenDaoUpgradeHelper:v2.2.1'
+ //ffmpeg
+ implementation 'com.github.microshow:RxFFmpeg:4.9.0'
}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index b4fb060..6dc1bff 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -38,5 +38,9 @@
android:name=".view.BigImageActivity"
android:screenOrientation="landscape"
android:theme="@style/Theme.BigImageActivity" />
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt b/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt
index 9643a69..6f48798 100644
--- a/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt
+++ b/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt
@@ -35,7 +35,9 @@
//根据不同的日期显示不同的改日期下的九宫格形式子文件
val videoDir = File(context.getExternalFilesDir(Environment.DIRECTORY_MOVIES), date)
videoDir.listFiles()?.forEach {
- fileBeans.add(it)
+ if (it.name.startsWith("t")) {
+ fileBeans.add(it)
+ }
}
val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), date)
diff --git a/app/src/main/java/com/casic/endoscope/base/BaseApplication.kt b/app/src/main/java/com/casic/endoscope/base/BaseApplication.kt
index 6439217..21cc4f5 100644
--- a/app/src/main/java/com/casic/endoscope/base/BaseApplication.kt
+++ b/app/src/main/java/com/casic/endoscope/base/BaseApplication.kt
@@ -5,6 +5,7 @@
import com.casic.endoscope.greendao.DaoSession
import com.casic.endoscope.utils.EndoscopeDevOpenHelper
import com.pengxh.kt.lite.utils.SaveKeyValues
+import io.microshow.rxffmpeg.RxFFmpegInvoke
import kotlin.properties.Delegates
class BaseApplication : Application() {
@@ -24,6 +25,7 @@
application = this
SaveKeyValues.initSharedPreferences(this)
initDataBase()
+ RxFFmpegInvoke.getInstance().setDebug(false)
}
private fun initDataBase() {
diff --git a/app/src/main/java/com/casic/endoscope/service/VideoTranscodeService.kt b/app/src/main/java/com/casic/endoscope/service/VideoTranscodeService.kt
new file mode 100644
index 0000000..ff353d3
--- /dev/null
+++ b/app/src/main/java/com/casic/endoscope/service/VideoTranscodeService.kt
@@ -0,0 +1,82 @@
+package com.casic.endoscope.service
+
+import android.app.Service
+import android.content.Intent
+import android.os.IBinder
+import android.util.Log
+import com.casic.endoscope.utils.FFmpegCommandHub
+import com.casic.endoscope.utils.ProjectConstant
+import com.pengxh.kt.lite.extensions.createLogFile
+import com.pengxh.kt.lite.extensions.writeToFile
+import io.microshow.rxffmpeg.RxFFmpegInvoke
+import io.microshow.rxffmpeg.RxFFmpegSubscriber
+import java.util.Timer
+import java.util.TimerTask
+
+class VideoTranscodeService : Service() {
+
+ private val kTag = "VideoTranscodeService"
+
+ override fun onBind(intent: Intent?): IBinder? {
+ return null
+ }
+
+ override fun onCreate() {
+ super.onCreate()
+ Log.d(kTag, "onCreate => ")
+ }
+
+
+ /**
+ * 执行该方法后,Service 会启动并在后台无限期执行
+ * 需要调用 stopSelf() 或 stopService() 来结束Service
+ * */
+ override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
+ //定时遍历缓存,看是否有新的视频被录制
+ Timer().schedule(object : TimerTask() {
+ override fun run() {
+ if (ProjectConstant.VIDEO_PATH_STACK.isNotEmpty()) {
+ transcodeVideo(ProjectConstant.VIDEO_PATH_STACK.pop())
+ }
+ }
+ }, 0, 1000)
+ return START_NOT_STICKY
+ }
+
+ //开始后台转码
+ private fun transcodeVideo(inputPath: String) {
+ /**
+ * //storage/emulated/0/Android/data/com.casic.endoscope/files/Movies/2024-02-21/20240221161555.mp4
+ * */
+ val lastIndex = inputPath.lastIndexOf("/")
+ val fileName = inputPath.drop(lastIndex + 1)
+ //文件名前面+t
+ val newFileName = fileName.reversed().plus("t").reversed()
+ val outputPath = inputPath.replace(fileName, newFileName)
+
+ RxFFmpegInvoke.getInstance()
+ .runCommandRxJava(FFmpegCommandHub.createVideoTranscodeCommand(inputPath, outputPath))
+ .subscribe(object : RxFFmpegSubscriber() {
+ override fun onError(message: String?) {
+ message?.writeToFile(createLogFile())
+ }
+
+ override fun onFinish() {
+ Log.d(kTag, "onFinish => $outputPath 转码完成")
+ }
+
+ override fun onProgress(progress: Int, progressTime: Long) {
+ Log.d(kTag, "onProgress => $progress")
+ }
+
+ override fun onCancel() {
+
+ }
+ })
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ Log.d(kTag, "onDestroy => ")
+ }
+}
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index 796cfcc..166d246 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -13,6 +13,10 @@
targetSdkVersion 33
versionCode 1000
versionName "1.0.0.0"
+
+ ndk {
+ abiFilters "armeabi-v7a", "arm64-v8a", "x86", "x86_64"
+ }
}
buildTypes {
@@ -98,4 +102,6 @@
implementation 'org.greenrobot:greendao:3.3.0'
//数据库升级
implementation 'io.github.yuweiguocn:GreenDaoUpgradeHelper:v2.2.1'
+ //ffmpeg
+ implementation 'com.github.microshow:RxFFmpeg:4.9.0'
}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index b4fb060..6dc1bff 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -38,5 +38,9 @@
android:name=".view.BigImageActivity"
android:screenOrientation="landscape"
android:theme="@style/Theme.BigImageActivity" />
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt b/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt
index 9643a69..6f48798 100644
--- a/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt
+++ b/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt
@@ -35,7 +35,9 @@
//根据不同的日期显示不同的改日期下的九宫格形式子文件
val videoDir = File(context.getExternalFilesDir(Environment.DIRECTORY_MOVIES), date)
videoDir.listFiles()?.forEach {
- fileBeans.add(it)
+ if (it.name.startsWith("t")) {
+ fileBeans.add(it)
+ }
}
val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), date)
diff --git a/app/src/main/java/com/casic/endoscope/base/BaseApplication.kt b/app/src/main/java/com/casic/endoscope/base/BaseApplication.kt
index 6439217..21cc4f5 100644
--- a/app/src/main/java/com/casic/endoscope/base/BaseApplication.kt
+++ b/app/src/main/java/com/casic/endoscope/base/BaseApplication.kt
@@ -5,6 +5,7 @@
import com.casic.endoscope.greendao.DaoSession
import com.casic.endoscope.utils.EndoscopeDevOpenHelper
import com.pengxh.kt.lite.utils.SaveKeyValues
+import io.microshow.rxffmpeg.RxFFmpegInvoke
import kotlin.properties.Delegates
class BaseApplication : Application() {
@@ -24,6 +25,7 @@
application = this
SaveKeyValues.initSharedPreferences(this)
initDataBase()
+ RxFFmpegInvoke.getInstance().setDebug(false)
}
private fun initDataBase() {
diff --git a/app/src/main/java/com/casic/endoscope/service/VideoTranscodeService.kt b/app/src/main/java/com/casic/endoscope/service/VideoTranscodeService.kt
new file mode 100644
index 0000000..ff353d3
--- /dev/null
+++ b/app/src/main/java/com/casic/endoscope/service/VideoTranscodeService.kt
@@ -0,0 +1,82 @@
+package com.casic.endoscope.service
+
+import android.app.Service
+import android.content.Intent
+import android.os.IBinder
+import android.util.Log
+import com.casic.endoscope.utils.FFmpegCommandHub
+import com.casic.endoscope.utils.ProjectConstant
+import com.pengxh.kt.lite.extensions.createLogFile
+import com.pengxh.kt.lite.extensions.writeToFile
+import io.microshow.rxffmpeg.RxFFmpegInvoke
+import io.microshow.rxffmpeg.RxFFmpegSubscriber
+import java.util.Timer
+import java.util.TimerTask
+
+class VideoTranscodeService : Service() {
+
+ private val kTag = "VideoTranscodeService"
+
+ override fun onBind(intent: Intent?): IBinder? {
+ return null
+ }
+
+ override fun onCreate() {
+ super.onCreate()
+ Log.d(kTag, "onCreate => ")
+ }
+
+
+ /**
+ * 执行该方法后,Service 会启动并在后台无限期执行
+ * 需要调用 stopSelf() 或 stopService() 来结束Service
+ * */
+ override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
+ //定时遍历缓存,看是否有新的视频被录制
+ Timer().schedule(object : TimerTask() {
+ override fun run() {
+ if (ProjectConstant.VIDEO_PATH_STACK.isNotEmpty()) {
+ transcodeVideo(ProjectConstant.VIDEO_PATH_STACK.pop())
+ }
+ }
+ }, 0, 1000)
+ return START_NOT_STICKY
+ }
+
+ //开始后台转码
+ private fun transcodeVideo(inputPath: String) {
+ /**
+ * //storage/emulated/0/Android/data/com.casic.endoscope/files/Movies/2024-02-21/20240221161555.mp4
+ * */
+ val lastIndex = inputPath.lastIndexOf("/")
+ val fileName = inputPath.drop(lastIndex + 1)
+ //文件名前面+t
+ val newFileName = fileName.reversed().plus("t").reversed()
+ val outputPath = inputPath.replace(fileName, newFileName)
+
+ RxFFmpegInvoke.getInstance()
+ .runCommandRxJava(FFmpegCommandHub.createVideoTranscodeCommand(inputPath, outputPath))
+ .subscribe(object : RxFFmpegSubscriber() {
+ override fun onError(message: String?) {
+ message?.writeToFile(createLogFile())
+ }
+
+ override fun onFinish() {
+ Log.d(kTag, "onFinish => $outputPath 转码完成")
+ }
+
+ override fun onProgress(progress: Int, progressTime: Long) {
+ Log.d(kTag, "onProgress => $progress")
+ }
+
+ override fun onCancel() {
+
+ }
+ })
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ Log.d(kTag, "onDestroy => ")
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/utils/FFmpegCommandHub.kt b/app/src/main/java/com/casic/endoscope/utils/FFmpegCommandHub.kt
new file mode 100644
index 0000000..128fbd8
--- /dev/null
+++ b/app/src/main/java/com/casic/endoscope/utils/FFmpegCommandHub.kt
@@ -0,0 +1,19 @@
+package com.casic.endoscope.utils
+
+import io.microshow.rxffmpeg.RxFFmpegCommandList
+
+object FFmpegCommandHub {
+
+ /**
+ * 海康视频转码指令
+ * */
+ fun createVideoTranscodeCommand(inputFilePath: String, outputFilePath: String): Array {
+ val commandParams = RxFFmpegCommandList()
+ commandParams.append("-i")
+ commandParams.append(inputFilePath)
+ commandParams.append("-c:v")
+ commandParams.append("libx264")
+ commandParams.append(outputFilePath)
+ return commandParams.build()
+ }
+}
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index 796cfcc..166d246 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -13,6 +13,10 @@
targetSdkVersion 33
versionCode 1000
versionName "1.0.0.0"
+
+ ndk {
+ abiFilters "armeabi-v7a", "arm64-v8a", "x86", "x86_64"
+ }
}
buildTypes {
@@ -98,4 +102,6 @@
implementation 'org.greenrobot:greendao:3.3.0'
//数据库升级
implementation 'io.github.yuweiguocn:GreenDaoUpgradeHelper:v2.2.1'
+ //ffmpeg
+ implementation 'com.github.microshow:RxFFmpeg:4.9.0'
}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index b4fb060..6dc1bff 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -38,5 +38,9 @@
android:name=".view.BigImageActivity"
android:screenOrientation="landscape"
android:theme="@style/Theme.BigImageActivity" />
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt b/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt
index 9643a69..6f48798 100644
--- a/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt
+++ b/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt
@@ -35,7 +35,9 @@
//根据不同的日期显示不同的改日期下的九宫格形式子文件
val videoDir = File(context.getExternalFilesDir(Environment.DIRECTORY_MOVIES), date)
videoDir.listFiles()?.forEach {
- fileBeans.add(it)
+ if (it.name.startsWith("t")) {
+ fileBeans.add(it)
+ }
}
val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), date)
diff --git a/app/src/main/java/com/casic/endoscope/base/BaseApplication.kt b/app/src/main/java/com/casic/endoscope/base/BaseApplication.kt
index 6439217..21cc4f5 100644
--- a/app/src/main/java/com/casic/endoscope/base/BaseApplication.kt
+++ b/app/src/main/java/com/casic/endoscope/base/BaseApplication.kt
@@ -5,6 +5,7 @@
import com.casic.endoscope.greendao.DaoSession
import com.casic.endoscope.utils.EndoscopeDevOpenHelper
import com.pengxh.kt.lite.utils.SaveKeyValues
+import io.microshow.rxffmpeg.RxFFmpegInvoke
import kotlin.properties.Delegates
class BaseApplication : Application() {
@@ -24,6 +25,7 @@
application = this
SaveKeyValues.initSharedPreferences(this)
initDataBase()
+ RxFFmpegInvoke.getInstance().setDebug(false)
}
private fun initDataBase() {
diff --git a/app/src/main/java/com/casic/endoscope/service/VideoTranscodeService.kt b/app/src/main/java/com/casic/endoscope/service/VideoTranscodeService.kt
new file mode 100644
index 0000000..ff353d3
--- /dev/null
+++ b/app/src/main/java/com/casic/endoscope/service/VideoTranscodeService.kt
@@ -0,0 +1,82 @@
+package com.casic.endoscope.service
+
+import android.app.Service
+import android.content.Intent
+import android.os.IBinder
+import android.util.Log
+import com.casic.endoscope.utils.FFmpegCommandHub
+import com.casic.endoscope.utils.ProjectConstant
+import com.pengxh.kt.lite.extensions.createLogFile
+import com.pengxh.kt.lite.extensions.writeToFile
+import io.microshow.rxffmpeg.RxFFmpegInvoke
+import io.microshow.rxffmpeg.RxFFmpegSubscriber
+import java.util.Timer
+import java.util.TimerTask
+
+class VideoTranscodeService : Service() {
+
+ private val kTag = "VideoTranscodeService"
+
+ override fun onBind(intent: Intent?): IBinder? {
+ return null
+ }
+
+ override fun onCreate() {
+ super.onCreate()
+ Log.d(kTag, "onCreate => ")
+ }
+
+
+ /**
+ * 执行该方法后,Service 会启动并在后台无限期执行
+ * 需要调用 stopSelf() 或 stopService() 来结束Service
+ * */
+ override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
+ //定时遍历缓存,看是否有新的视频被录制
+ Timer().schedule(object : TimerTask() {
+ override fun run() {
+ if (ProjectConstant.VIDEO_PATH_STACK.isNotEmpty()) {
+ transcodeVideo(ProjectConstant.VIDEO_PATH_STACK.pop())
+ }
+ }
+ }, 0, 1000)
+ return START_NOT_STICKY
+ }
+
+ //开始后台转码
+ private fun transcodeVideo(inputPath: String) {
+ /**
+ * //storage/emulated/0/Android/data/com.casic.endoscope/files/Movies/2024-02-21/20240221161555.mp4
+ * */
+ val lastIndex = inputPath.lastIndexOf("/")
+ val fileName = inputPath.drop(lastIndex + 1)
+ //文件名前面+t
+ val newFileName = fileName.reversed().plus("t").reversed()
+ val outputPath = inputPath.replace(fileName, newFileName)
+
+ RxFFmpegInvoke.getInstance()
+ .runCommandRxJava(FFmpegCommandHub.createVideoTranscodeCommand(inputPath, outputPath))
+ .subscribe(object : RxFFmpegSubscriber() {
+ override fun onError(message: String?) {
+ message?.writeToFile(createLogFile())
+ }
+
+ override fun onFinish() {
+ Log.d(kTag, "onFinish => $outputPath 转码完成")
+ }
+
+ override fun onProgress(progress: Int, progressTime: Long) {
+ Log.d(kTag, "onProgress => $progress")
+ }
+
+ override fun onCancel() {
+
+ }
+ })
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ Log.d(kTag, "onDestroy => ")
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/utils/FFmpegCommandHub.kt b/app/src/main/java/com/casic/endoscope/utils/FFmpegCommandHub.kt
new file mode 100644
index 0000000..128fbd8
--- /dev/null
+++ b/app/src/main/java/com/casic/endoscope/utils/FFmpegCommandHub.kt
@@ -0,0 +1,19 @@
+package com.casic.endoscope.utils
+
+import io.microshow.rxffmpeg.RxFFmpegCommandList
+
+object FFmpegCommandHub {
+
+ /**
+ * 海康视频转码指令
+ * */
+ fun createVideoTranscodeCommand(inputFilePath: String, outputFilePath: String): Array {
+ val commandParams = RxFFmpegCommandList()
+ commandParams.append("-i")
+ commandParams.append(inputFilePath)
+ commandParams.append("-c:v")
+ commandParams.append("libx264")
+ commandParams.append(outputFilePath)
+ return commandParams.build()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/utils/ProjectConstant.kt b/app/src/main/java/com/casic/endoscope/utils/ProjectConstant.kt
index 1db0579..6c561a8 100644
--- a/app/src/main/java/com/casic/endoscope/utils/ProjectConstant.kt
+++ b/app/src/main/java/com/casic/endoscope/utils/ProjectConstant.kt
@@ -1,9 +1,14 @@
package com.casic.endoscope.utils
+import java.util.Stack
+
object ProjectConstant {
//海康摄像头参数
const val HK_NET_IP = "192.168.43.121"
const val HK_NET_PORT = "8000"
const val HK_NET_USERNAME = "admin"
const val HK_NET_PASSWORD = "casic203"
+
+ //待转码视频路径
+ val VIDEO_PATH_STACK = Stack()
}
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index 796cfcc..166d246 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -13,6 +13,10 @@
targetSdkVersion 33
versionCode 1000
versionName "1.0.0.0"
+
+ ndk {
+ abiFilters "armeabi-v7a", "arm64-v8a", "x86", "x86_64"
+ }
}
buildTypes {
@@ -98,4 +102,6 @@
implementation 'org.greenrobot:greendao:3.3.0'
//数据库升级
implementation 'io.github.yuweiguocn:GreenDaoUpgradeHelper:v2.2.1'
+ //ffmpeg
+ implementation 'com.github.microshow:RxFFmpeg:4.9.0'
}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index b4fb060..6dc1bff 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -38,5 +38,9 @@
android:name=".view.BigImageActivity"
android:screenOrientation="landscape"
android:theme="@style/Theme.BigImageActivity" />
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt b/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt
index 9643a69..6f48798 100644
--- a/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt
+++ b/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt
@@ -35,7 +35,9 @@
//根据不同的日期显示不同的改日期下的九宫格形式子文件
val videoDir = File(context.getExternalFilesDir(Environment.DIRECTORY_MOVIES), date)
videoDir.listFiles()?.forEach {
- fileBeans.add(it)
+ if (it.name.startsWith("t")) {
+ fileBeans.add(it)
+ }
}
val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), date)
diff --git a/app/src/main/java/com/casic/endoscope/base/BaseApplication.kt b/app/src/main/java/com/casic/endoscope/base/BaseApplication.kt
index 6439217..21cc4f5 100644
--- a/app/src/main/java/com/casic/endoscope/base/BaseApplication.kt
+++ b/app/src/main/java/com/casic/endoscope/base/BaseApplication.kt
@@ -5,6 +5,7 @@
import com.casic.endoscope.greendao.DaoSession
import com.casic.endoscope.utils.EndoscopeDevOpenHelper
import com.pengxh.kt.lite.utils.SaveKeyValues
+import io.microshow.rxffmpeg.RxFFmpegInvoke
import kotlin.properties.Delegates
class BaseApplication : Application() {
@@ -24,6 +25,7 @@
application = this
SaveKeyValues.initSharedPreferences(this)
initDataBase()
+ RxFFmpegInvoke.getInstance().setDebug(false)
}
private fun initDataBase() {
diff --git a/app/src/main/java/com/casic/endoscope/service/VideoTranscodeService.kt b/app/src/main/java/com/casic/endoscope/service/VideoTranscodeService.kt
new file mode 100644
index 0000000..ff353d3
--- /dev/null
+++ b/app/src/main/java/com/casic/endoscope/service/VideoTranscodeService.kt
@@ -0,0 +1,82 @@
+package com.casic.endoscope.service
+
+import android.app.Service
+import android.content.Intent
+import android.os.IBinder
+import android.util.Log
+import com.casic.endoscope.utils.FFmpegCommandHub
+import com.casic.endoscope.utils.ProjectConstant
+import com.pengxh.kt.lite.extensions.createLogFile
+import com.pengxh.kt.lite.extensions.writeToFile
+import io.microshow.rxffmpeg.RxFFmpegInvoke
+import io.microshow.rxffmpeg.RxFFmpegSubscriber
+import java.util.Timer
+import java.util.TimerTask
+
+class VideoTranscodeService : Service() {
+
+ private val kTag = "VideoTranscodeService"
+
+ override fun onBind(intent: Intent?): IBinder? {
+ return null
+ }
+
+ override fun onCreate() {
+ super.onCreate()
+ Log.d(kTag, "onCreate => ")
+ }
+
+
+ /**
+ * 执行该方法后,Service 会启动并在后台无限期执行
+ * 需要调用 stopSelf() 或 stopService() 来结束Service
+ * */
+ override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
+ //定时遍历缓存,看是否有新的视频被录制
+ Timer().schedule(object : TimerTask() {
+ override fun run() {
+ if (ProjectConstant.VIDEO_PATH_STACK.isNotEmpty()) {
+ transcodeVideo(ProjectConstant.VIDEO_PATH_STACK.pop())
+ }
+ }
+ }, 0, 1000)
+ return START_NOT_STICKY
+ }
+
+ //开始后台转码
+ private fun transcodeVideo(inputPath: String) {
+ /**
+ * //storage/emulated/0/Android/data/com.casic.endoscope/files/Movies/2024-02-21/20240221161555.mp4
+ * */
+ val lastIndex = inputPath.lastIndexOf("/")
+ val fileName = inputPath.drop(lastIndex + 1)
+ //文件名前面+t
+ val newFileName = fileName.reversed().plus("t").reversed()
+ val outputPath = inputPath.replace(fileName, newFileName)
+
+ RxFFmpegInvoke.getInstance()
+ .runCommandRxJava(FFmpegCommandHub.createVideoTranscodeCommand(inputPath, outputPath))
+ .subscribe(object : RxFFmpegSubscriber() {
+ override fun onError(message: String?) {
+ message?.writeToFile(createLogFile())
+ }
+
+ override fun onFinish() {
+ Log.d(kTag, "onFinish => $outputPath 转码完成")
+ }
+
+ override fun onProgress(progress: Int, progressTime: Long) {
+ Log.d(kTag, "onProgress => $progress")
+ }
+
+ override fun onCancel() {
+
+ }
+ })
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ Log.d(kTag, "onDestroy => ")
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/utils/FFmpegCommandHub.kt b/app/src/main/java/com/casic/endoscope/utils/FFmpegCommandHub.kt
new file mode 100644
index 0000000..128fbd8
--- /dev/null
+++ b/app/src/main/java/com/casic/endoscope/utils/FFmpegCommandHub.kt
@@ -0,0 +1,19 @@
+package com.casic.endoscope.utils
+
+import io.microshow.rxffmpeg.RxFFmpegCommandList
+
+object FFmpegCommandHub {
+
+ /**
+ * 海康视频转码指令
+ * */
+ fun createVideoTranscodeCommand(inputFilePath: String, outputFilePath: String): Array {
+ val commandParams = RxFFmpegCommandList()
+ commandParams.append("-i")
+ commandParams.append(inputFilePath)
+ commandParams.append("-c:v")
+ commandParams.append("libx264")
+ commandParams.append(outputFilePath)
+ return commandParams.build()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/utils/ProjectConstant.kt b/app/src/main/java/com/casic/endoscope/utils/ProjectConstant.kt
index 1db0579..6c561a8 100644
--- a/app/src/main/java/com/casic/endoscope/utils/ProjectConstant.kt
+++ b/app/src/main/java/com/casic/endoscope/utils/ProjectConstant.kt
@@ -1,9 +1,14 @@
package com.casic.endoscope.utils
+import java.util.Stack
+
object ProjectConstant {
//海康摄像头参数
const val HK_NET_IP = "192.168.43.121"
const val HK_NET_PORT = "8000"
const val HK_NET_USERNAME = "admin"
const val HK_NET_PASSWORD = "casic203"
+
+ //待转码视频路径
+ val VIDEO_PATH_STACK = Stack()
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/view/MainActivity.kt b/app/src/main/java/com/casic/endoscope/view/MainActivity.kt
index 37ce0b4..0a65486 100644
--- a/app/src/main/java/com/casic/endoscope/view/MainActivity.kt
+++ b/app/src/main/java/com/casic/endoscope/view/MainActivity.kt
@@ -1,6 +1,7 @@
package com.casic.endoscope.view
import android.annotation.SuppressLint
+import android.content.Intent
import android.graphics.PixelFormat
import android.os.Bundle
import android.os.Handler
@@ -20,6 +21,7 @@
import com.casic.endoscope.extensions.createVideoFileDir
import com.casic.endoscope.extensions.getChannel
import com.casic.endoscope.extensions.toTime
+import com.casic.endoscope.service.VideoTranscodeService
import com.casic.endoscope.utils.DataBaseManager
import com.casic.endoscope.utils.ProjectConstant
import com.casic.endoscope.utils.hk.MessageCodeHub
@@ -46,6 +48,7 @@
import java.util.Timer
import java.util.TimerTask
+
@SuppressLint("all")
class MainActivity : KotlinBaseActivity(), SurfaceHolder.Callback,
Handler.Callback {
@@ -80,8 +83,10 @@
private var seconds = 0L
private var dataBeans: MutableList = ArrayList()
private var selectedItems: MutableList = ArrayList()
+ private var inputVideoPath = ""
private lateinit var weakReferenceHandler: WeakReferenceHandler
private lateinit var dataAdapter: CameraPointAdapter
+ private lateinit var serviceIntent: Intent
override fun initViewBinding(): ActivityMainBinding {
return ActivityMainBinding.inflate(layoutInflater)
@@ -94,6 +99,16 @@
//显示数据
weakReferenceHandler.sendEmptyMessage(messageCode)
+
+// ProjectConstant.VIDEO_PATH_STACK.push("/storage/self/primary/Android/data/com.casic.endoscope/files/Movies/2024-02-20/20240220113648.mp4")
+
+ serviceIntent = Intent(this, VideoTranscodeService::class.java)
+ }
+
+ override fun onResume() {
+ super.onResume()
+ //启动视频转码服务
+ startService(serviceIntent)
}
override fun handleMessage(msg: Message): Boolean {
@@ -145,8 +160,8 @@
//视频录制
binding.videoButton.setOnClickListener {
if (isPreviewSuccess) {
- val videoPath = "/${createVideoFileDir()}/${timeFormat.format(Date())}.mp4"
- hkSDK.NET_DVR_SaveRealData(returnUserId, videoPath)
+ inputVideoPath = "/${createVideoFileDir()}/${timeFormat.format(Date())}.mp4"
+ hkSDK.NET_DVR_SaveRealData(returnUserId, inputVideoPath)
binding.videoStateView.visibility = View.VISIBLE
} else {
"摄像头预览未打开,无法录制视频".show(this)
@@ -157,6 +172,7 @@
//停止视频抓取
hkSDK.NET_DVR_StopSaveRealData(returnUserId)
binding.videoStateView.visibility = View.INVISIBLE
+ ProjectConstant.VIDEO_PATH_STACK.push(inputVideoPath)
"视频录制成功".show(this)
true
}
@@ -528,6 +544,7 @@
override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
if (keyCode == KeyEvent.KEYCODE_BACK) {
if (System.currentTimeMillis() - clickTime > 2000) {
+ stopService(serviceIntent)
"再按一次退出应用".show(this)
clickTime = System.currentTimeMillis()
return true