From 2a71427dfbc10ea6fbad0053e44121532d20c511 Mon Sep 17 00:00:00 2001
From: Lonely dreamers <1240413544@qq.com>
Date: Mon, 25 Apr 2022 23:33:27 +0800
Subject: [PATCH] Feature: add compose ui
---
.../controller/AudioTrackController.kt | 2 +-
.../controller/MediaMetadataController.kt | 8 +++-
.../com/frank/androidmedia/util/WavUtil.kt | 4 +-
app/build.gradle | 44 +++++++++++++++++
app/src/main/AndroidManifest.xml | 30 +++++++-----
.../ffmpeg/activity/AudioPlayActivity.kt | 2 +-
.../frank/ffmpeg/activity/ComposeActivity.kt | 43 +++++++++++++++++
.../frank/ffmpeg/activity/FilterActivity.kt | 4 +-
.../com/frank/ffmpeg/activity/LiveActivity.kt | 1 +
.../com/frank/ffmpeg/activity/MainActivity.kt | 22 +++++----
.../frank/ffmpeg/activity/ui/theme/Color.kt | 8 ++++
.../frank/ffmpeg/activity/ui/theme/Shape.kt | 11 +++++
.../frank/ffmpeg/activity/ui/theme/Theme.kt | 47 +++++++++++++++++++
.../frank/ffmpeg/activity/ui/theme/Type.kt | 28 +++++++++++
app/src/main/res/values-en/strings.xml | 1 +
app/src/main/res/values/strings.xml | 1 +
build.gradle | 11 +++--
gradle.properties | 2 +-
.../main/java/com/frank/mp3/Mp3Converter.kt | 16 ++++---
19 files changed, 243 insertions(+), 42 deletions(-)
create mode 100644 app/src/main/java/com/frank/ffmpeg/activity/ComposeActivity.kt
create mode 100644 app/src/main/java/com/frank/ffmpeg/activity/ui/theme/Color.kt
create mode 100644 app/src/main/java/com/frank/ffmpeg/activity/ui/theme/Shape.kt
create mode 100644 app/src/main/java/com/frank/ffmpeg/activity/ui/theme/Theme.kt
create mode 100644 app/src/main/java/com/frank/ffmpeg/activity/ui/theme/Type.kt
diff --git a/AndroidMedia/src/main/java/com/frank/androidmedia/controller/AudioTrackController.kt b/AndroidMedia/src/main/java/com/frank/androidmedia/controller/AudioTrackController.kt
index 5d19198..80dcadc 100644
--- a/AndroidMedia/src/main/java/com/frank/androidmedia/controller/AudioTrackController.kt
+++ b/AndroidMedia/src/main/java/com/frank/androidmedia/controller/AudioTrackController.kt
@@ -49,7 +49,7 @@ open class AudioTrackController {
private fun initMediaCodec(mediaFormat: MediaFormat): Boolean {
val mimeType = mediaFormat.getString(MediaFormat.KEY_MIME)
- mediaCodec = MediaCodec.createDecoderByType(mimeType)
+ mediaCodec = MediaCodec.createDecoderByType(mimeType.toString())
return try {
mediaCodec!!.configure(mediaFormat, null, null, 0)
mediaCodec!!.start()
diff --git a/AndroidMedia/src/main/java/com/frank/androidmedia/controller/MediaMetadataController.kt b/AndroidMedia/src/main/java/com/frank/androidmedia/controller/MediaMetadataController.kt
index 6a0dc6a..9843c44 100644
--- a/AndroidMedia/src/main/java/com/frank/androidmedia/controller/MediaMetadataController.kt
+++ b/AndroidMedia/src/main/java/com/frank/androidmedia/controller/MediaMetadataController.kt
@@ -57,7 +57,9 @@ open class MediaMetadataController {
try {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
val frameRateStr = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_CAPTURE_FRAMERATE)
- frameRate = frameRateStr.toFloat()
+ if (frameRateStr != null) {
+ frameRate = frameRateStr.toFloat()
+ }
Log.i(TAG, "frameRate=$frameRate")
}
} catch (e: Exception) {
@@ -69,7 +71,9 @@ open class MediaMetadataController {
thumbnail = retriever.getFrameAtTime(0)
} else if (hasAudioStr != null && "yes" == hasAudioStr) {
val byteArray = retriever.embeddedPicture
- thumbnail = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.size, null)
+ if (byteArray != null) {
+ thumbnail = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.size, null)
+ }
}
if (thumbnail != null) {
Log.i(TAG, "thumbnail width=${thumbnail?.width}, height=${thumbnail?.height}")
diff --git a/AndroidMedia/src/main/java/com/frank/androidmedia/util/WavUtil.kt b/AndroidMedia/src/main/java/com/frank/androidmedia/util/WavUtil.kt
index 58de8db..d4d1d42 100644
--- a/AndroidMedia/src/main/java/com/frank/androidmedia/util/WavUtil.kt
+++ b/AndroidMedia/src/main/java/com/frank/androidmedia/util/WavUtil.kt
@@ -31,7 +31,7 @@ object WavUtil {
val h: ByteArray = try {
header.header
} catch (e1: IOException) {
- Log.e("WavUtil", e1.message)
+ Log.e("WavUtil", e1.message.toString())
return false
}
if (h.size != 44) return false
@@ -52,7 +52,7 @@ object WavUtil {
inStream.close()
ouStream.close()
} catch (e: IOException) {
- Log.e("WavUtil", e.message)
+ Log.e("WavUtil", e.message.toString())
return false
}
if (deletePcmFile) {
diff --git a/app/build.gradle b/app/build.gradle
index 51cd81d..19ecd52 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -20,6 +20,9 @@ android {
ndk {
abiFilters "armeabi-v7a", "arm64-v8a"
}
+ vectorDrawables {
+ useSupportLibrary true
+ }
}
buildTypes {
release {
@@ -51,6 +54,21 @@ android {
pickFirst 'lib/arm64-v8a/libmp3lame.so'
pickFirst 'lib/armeabi-v7a/libffmpeg.so'
pickFirst 'lib/arm64-v8a/libffmpeg.so'
+ resources {
+ excludes += '/META-INF/{AL2.0,LGPL2.1}'
+ }
+ }
+ kotlinOptions {
+ jvmTarget = '1.8'
+ }
+ buildFeatures {
+ compose true
+ }
+ buildFeatures {
+ compose true
+ }
+ composeOptions {
+ kotlinCompilerExtensionVersion compose_version
}
}
@@ -65,4 +83,30 @@ dependencies {
implementation project(':AndroidMedia')
//implementation "libmp3" if you need mp3-lite module
// implementation project(':libmp3')
+
+
+ // compose start
+ implementation 'androidx.compose.ui:ui:1.1.1'
+ // Tooling support (Previews, etc.)
+ implementation 'androidx.compose.ui:ui-tooling:1.1.1'
+ // Foundation (Border, Background, Box, Image, Scroll, shapes, animations, etc.)
+ implementation 'androidx.compose.foundation:foundation:1.1.1'
+ // Material Design
+ implementation 'androidx.compose.material:material:1.1.1'
+ // Material design icons
+ implementation 'androidx.compose.material:material-icons-core:1.1.1'
+ implementation 'androidx.compose.material:material-icons-extended:1.1.1'
+ // Integration with activities
+ implementation 'androidx.activity:activity-compose:1.4.0'
+ // Integration with ViewModels
+ implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:2.4.1'
+ // Integration with observables
+ implementation 'androidx.compose.runtime:runtime-livedata:1.1.1'
+ implementation 'androidx.compose.runtime:runtime-rxjava2:1.1.1'
+ implementation "androidx.compose.ui:ui-tooling-preview:$compose_version"
+ implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
+
+ // UI Tests
+ androidTestImplementation 'androidx.compose.ui:ui-test-junit4:1.1.1'
+ // compose end
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index eb4b9e4..cc94e53 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -3,17 +3,6 @@
xmlns:tools="http://schemas.android.com/tools"
package="com.frank.ffmpeg">
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
@@ -47,5 +40,16 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/frank/ffmpeg/activity/AudioPlayActivity.kt b/app/src/main/java/com/frank/ffmpeg/activity/AudioPlayActivity.kt
index 2943b73..f2d8fe8 100644
--- a/app/src/main/java/com/frank/ffmpeg/activity/AudioPlayActivity.kt
+++ b/app/src/main/java/com/frank/ffmpeg/activity/AudioPlayActivity.kt
@@ -48,7 +48,7 @@ class AudioPlayActivity : AppCompatActivity() {
private val mHandler: Handler = @SuppressLint("HandlerLeak")
object : Handler() {
- override fun handleMessage(msg: Message?) {
+ override fun handleMessage(msg: Message) {
super.handleMessage(msg)
when (msg?.what) {
MSG_TIME -> {
diff --git a/app/src/main/java/com/frank/ffmpeg/activity/ComposeActivity.kt b/app/src/main/java/com/frank/ffmpeg/activity/ComposeActivity.kt
new file mode 100644
index 0000000..1277842
--- /dev/null
+++ b/app/src/main/java/com/frank/ffmpeg/activity/ComposeActivity.kt
@@ -0,0 +1,43 @@
+package com.frank.ffmpeg.activity
+
+import android.os.Bundle
+import androidx.activity.ComponentActivity
+import androidx.activity.compose.setContent
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.material.MaterialTheme
+import androidx.compose.material.Surface
+import androidx.compose.material.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.tooling.preview.Preview
+import com.frank.ffmpeg.activity.ui.theme.FFmpegAndroidTheme
+
+class ComposeActivity : ComponentActivity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContent {
+ FFmpegAndroidTheme {
+ // A surface container using the 'background' color from the theme
+ Surface(
+ modifier = Modifier.fillMaxSize(),
+ color = MaterialTheme.colors.background
+ ) {
+ Greeting("Android")
+ }
+ }
+ }
+ }
+}
+
+@Composable
+fun Greeting(name: String) {
+ Text(text = "Hello $name!")
+}
+
+@Preview(showBackground = true)
+@Composable
+fun DefaultPreview() {
+ FFmpegAndroidTheme {
+ Greeting("Android")
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/frank/ffmpeg/activity/FilterActivity.kt b/app/src/main/java/com/frank/ffmpeg/activity/FilterActivity.kt
index 8feae3c..cb527de 100644
--- a/app/src/main/java/com/frank/ffmpeg/activity/FilterActivity.kt
+++ b/app/src/main/java/com/frank/ffmpeg/activity/FilterActivity.kt
@@ -87,7 +87,7 @@ class FilterActivity : BaseActivity(), SurfaceHolder.Callback {
registerLister()
hideRunnable = HideRunnable()
- mHandler.postDelayed(hideRunnable, DELAY_TIME.toLong())
+ mHandler.postDelayed(hideRunnable!!, DELAY_TIME.toLong())
}
private fun initView() {
@@ -126,7 +126,7 @@ class FilterActivity : BaseActivity(), SurfaceHolder.Callback {
btnSelect!!.visibility = View.VISIBLE
btnSound!!.visibility = View.VISIBLE
recyclerView!!.visibility = View.VISIBLE
- mHandler.postDelayed(hideRunnable, DELAY_TIME.toLong())
+ hideRunnable?.let { it1 -> mHandler.postDelayed(it1, DELAY_TIME.toLong()) }
}
btnSound!!.setOnCheckedChangeListener { buttonView, isChecked -> setPlayAudio() }
diff --git a/app/src/main/java/com/frank/ffmpeg/activity/LiveActivity.kt b/app/src/main/java/com/frank/ffmpeg/activity/LiveActivity.kt
index 91f4e73..71377f9 100644
--- a/app/src/main/java/com/frank/ffmpeg/activity/LiveActivity.kt
+++ b/app/src/main/java/com/frank/ffmpeg/activity/LiveActivity.kt
@@ -16,6 +16,7 @@ import android.view.View
import android.widget.CompoundButton
import android.widget.Toast
import android.widget.ToggleButton
+import androidx.compose.runtime.Composable
import com.frank.ffmpeg.R
import com.frank.ffmpeg.handler.ConnectionReceiver
diff --git a/app/src/main/java/com/frank/ffmpeg/activity/MainActivity.kt b/app/src/main/java/com/frank/ffmpeg/activity/MainActivity.kt
index b1555e9..b93e076 100644
--- a/app/src/main/java/com/frank/ffmpeg/activity/MainActivity.kt
+++ b/app/src/main/java/com/frank/ffmpeg/activity/MainActivity.kt
@@ -27,15 +27,17 @@ class MainActivity : BaseActivity() {
private fun initView() {
val list = listOf(
- getString(R.string.audio_handle),
- getString(R.string.video_handle),
- getString(R.string.media_handle),
- getString(R.string.video_push),
- getString(R.string.video_live),
- getString(R.string.video_filter),
- getString(R.string.video_preview),
- getString(R.string.media_probe),
- getString(R.string.audio_effect))
+ getString(R.string.audio_handle),
+ getString(R.string.video_handle),
+ getString(R.string.media_handle),
+ getString(R.string.video_push),
+ getString(R.string.video_live),
+ getString(R.string.video_filter),
+ getString(R.string.video_preview),
+ getString(R.string.media_probe),
+ getString(R.string.audio_effect),
+ getString(R.string.compose)
+ )
val viewWaterfall: RecyclerView = findViewById(R.id.list_main_item)
val layoutManager = StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL)
@@ -71,6 +73,8 @@ class MainActivity : BaseActivity() {
-> intent.setClass(this@MainActivity, ProbeFormatActivity::class.java)
8 //audio effect
-> intent.setClass(this@MainActivity, AudioEffectActivity::class.java)
+ 9
+ -> intent.setClass(this@MainActivity, ComposeActivity::class.java)
else -> {
}
}
diff --git a/app/src/main/java/com/frank/ffmpeg/activity/ui/theme/Color.kt b/app/src/main/java/com/frank/ffmpeg/activity/ui/theme/Color.kt
new file mode 100644
index 0000000..6ce7984
--- /dev/null
+++ b/app/src/main/java/com/frank/ffmpeg/activity/ui/theme/Color.kt
@@ -0,0 +1,8 @@
+package com.frank.ffmpeg.activity.ui.theme
+
+import androidx.compose.ui.graphics.Color
+
+val Purple200 = Color(0xFFBB86FC)
+val Purple500 = Color(0xFF6200EE)
+val Purple700 = Color(0xFF3700B3)
+val Teal200 = Color(0xFF03DAC5)
\ No newline at end of file
diff --git a/app/src/main/java/com/frank/ffmpeg/activity/ui/theme/Shape.kt b/app/src/main/java/com/frank/ffmpeg/activity/ui/theme/Shape.kt
new file mode 100644
index 0000000..8db6171
--- /dev/null
+++ b/app/src/main/java/com/frank/ffmpeg/activity/ui/theme/Shape.kt
@@ -0,0 +1,11 @@
+package com.frank.ffmpeg.activity.ui.theme
+
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material.Shapes
+import androidx.compose.ui.unit.dp
+
+val Shapes = Shapes(
+ small = RoundedCornerShape(4.dp),
+ medium = RoundedCornerShape(4.dp),
+ large = RoundedCornerShape(0.dp)
+)
\ No newline at end of file
diff --git a/app/src/main/java/com/frank/ffmpeg/activity/ui/theme/Theme.kt b/app/src/main/java/com/frank/ffmpeg/activity/ui/theme/Theme.kt
new file mode 100644
index 0000000..08c845d
--- /dev/null
+++ b/app/src/main/java/com/frank/ffmpeg/activity/ui/theme/Theme.kt
@@ -0,0 +1,47 @@
+package com.frank.ffmpeg.activity.ui.theme
+
+import androidx.compose.foundation.isSystemInDarkTheme
+import androidx.compose.material.MaterialTheme
+import androidx.compose.material.darkColors
+import androidx.compose.material.lightColors
+import androidx.compose.runtime.Composable
+
+private val DarkColorPalette = darkColors(
+ primary = Purple200,
+ primaryVariant = Purple700,
+ secondary = Teal200
+)
+
+private val LightColorPalette = lightColors(
+ primary = Purple500,
+ primaryVariant = Purple700,
+ secondary = Teal200
+
+ /* Other default colors to override
+ background = Color.White,
+ surface = Color.White,
+ onPrimary = Color.White,
+ onSecondary = Color.Black,
+ onBackground = Color.Black,
+ onSurface = Color.Black,
+ */
+)
+
+@Composable
+fun FFmpegAndroidTheme(
+ darkTheme: Boolean = isSystemInDarkTheme(),
+ content: @Composable () -> Unit
+) {
+ val colors = if (darkTheme) {
+ DarkColorPalette
+ } else {
+ LightColorPalette
+ }
+
+ MaterialTheme(
+ colors = colors,
+ typography = Typography,
+ shapes = Shapes,
+ content = content
+ )
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/frank/ffmpeg/activity/ui/theme/Type.kt b/app/src/main/java/com/frank/ffmpeg/activity/ui/theme/Type.kt
new file mode 100644
index 0000000..ed31e5a
--- /dev/null
+++ b/app/src/main/java/com/frank/ffmpeg/activity/ui/theme/Type.kt
@@ -0,0 +1,28 @@
+package com.frank.ffmpeg.activity.ui.theme
+
+import androidx.compose.material.Typography
+import androidx.compose.ui.text.TextStyle
+import androidx.compose.ui.text.font.FontFamily
+import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.unit.sp
+
+// Set of Material typography styles to start with
+val Typography = Typography(
+ body1 = TextStyle(
+ fontFamily = FontFamily.Default,
+ fontWeight = FontWeight.Normal,
+ fontSize = 16.sp
+ )
+ /* Other default text styles to override
+ button = TextStyle(
+ fontFamily = FontFamily.Default,
+ fontWeight = FontWeight.W500,
+ fontSize = 14.sp
+ ),
+ caption = TextStyle(
+ fontFamily = FontFamily.Default,
+ fontWeight = FontWeight.Normal,
+ fontSize = 12.sp
+ )
+ */
+)
\ No newline at end of file
diff --git a/app/src/main/res/values-en/strings.xml b/app/src/main/res/values-en/strings.xml
index be4a3d7..3bb7965 100644
--- a/app/src/main/res/values-en/strings.xml
+++ b/app/src/main/res/values-en/strings.xml
@@ -1,5 +1,6 @@
FFmpegAndroid
+ compose
Audio transform
Audio cut
Audio concat
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 9b49510..18deaa0 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -1,5 +1,6 @@
FFmpegAndroid
+ compose
音频转码
音频剪切
音频拼接
diff --git a/build.gradle b/build.gradle
index dcf1b31..c080a5f 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,6 +1,9 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
+ ext {
+ compose_version = '1.0.1'
+ }
ext.kotlin_version = '1.3.50'
repositories {
google()
@@ -8,7 +11,7 @@ buildscript {
}
dependencies {
classpath 'com.android.tools.build:gradle:7.1.3'
- classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.21"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
@@ -26,10 +29,10 @@ task clean(type: Delete) {
}
ext {
- compileSdkVersion = 28
- buildToolsVersion = '28.0.2'
+ compileSdkVersion = 31
+ buildToolsVersion = '31.0.2'
minSdkVersion = 21
- targetSdkVersion = 28
+ targetSdkVersion = 31
versionCode = 103000
versionName = "1.3.0"
}
\ No newline at end of file
diff --git a/gradle.properties b/gradle.properties
index 6c948f6..ce55f21 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -15,7 +15,7 @@
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
-org.gradle.jvmargs=-Xmx512m
+org.gradle.jvmargs=-Xmx4096m
android.enableJetifier=true
android.useAndroidX=true
diff --git a/libmp3/src/main/java/com/frank/mp3/Mp3Converter.kt b/libmp3/src/main/java/com/frank/mp3/Mp3Converter.kt
index 8666b78..317c4a9 100644
--- a/libmp3/src/main/java/com/frank/mp3/Mp3Converter.kt
+++ b/libmp3/src/main/java/com/frank/mp3/Mp3Converter.kt
@@ -227,13 +227,15 @@ open class Mp3Converter {
Log.i(TAG, "prepareDecode get mMediaFormat=$mMediaFormat")
val mime = mMediaFormat.getString(MediaFormat.KEY_MIME)
- if (mime.startsWith("audio")) {
- mMediaCodec = MediaCodec.createDecoderByType(mime)
- mMediaCodec!!.configure(mMediaFormat, null, null, 0)
- mediaExtractor!!.selectTrack(i)
- inSampleRate = mMediaFormat.getInteger(MediaFormat.KEY_SAMPLE_RATE)
- channels = mMediaFormat.getInteger(MediaFormat.KEY_CHANNEL_COUNT)
- break
+ if (mime != null) {
+ if (mime.startsWith("audio")) {
+ mMediaCodec = MediaCodec.createDecoderByType(mime)
+ mMediaCodec!!.configure(mMediaFormat, null, null, 0)
+ mediaExtractor!!.selectTrack(i)
+ inSampleRate = mMediaFormat.getInteger(MediaFormat.KEY_SAMPLE_RATE)
+ channels = mMediaFormat.getInteger(MediaFormat.KEY_CHANNEL_COUNT)
+ break
+ }
}
}
mMediaCodec!!.start()