temp fix full audio ffmpeg-kit

This commit is contained in:
shabinder 2021-08-25 16:23:17 +05:30
parent 363f0663c7
commit 487a27c4d3
4 changed files with 60 additions and 37 deletions

View File

@ -18,9 +18,9 @@
object Versions { object Versions {
// App's Version (To be bumped at each update) // App's Version (To be bumped at each update)
const val versionName = "3.2.1" const val versionName = "3.2.11"
const val versionCode = 22 const val versionCode = 23
// Kotlin // Kotlin
const val kotlinVersion = "1.5.21" const val kotlinVersion = "1.5.21"

View File

@ -19,7 +19,7 @@ kotlin {
dependencies { dependencies {
implementation(Extras.mp3agic) implementation(Extras.mp3agic)
implementation(Extras.Android.countly) implementation(Extras.Android.countly)
implementation(project(":ffmpeg-kit:android:ffmpeg-kit-android-lib")) implementation("com.arthenica:ffmpeg-kit-audio:4.4.LTS")
//api(files("$rootDir/libs/mobile-ffmpeg.aar")) //api(files("$rootDir/libs/mobile-ffmpeg.aar"))
} }
} }

View File

@ -65,7 +65,8 @@ class AndroidFileManager(
spotiFlyerDatabase: SpotiFlyerDatabase spotiFlyerDatabase: SpotiFlyerDatabase
) : FileManager { ) : FileManager {
@Suppress("DEPRECATION") @Suppress("DEPRECATION")
private val defaultBaseDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC).toString() private val defaultBaseDir =
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC).toString()
override fun fileSeparator(): String = File.separator override fun fileSeparator(): String = File.separator
@ -124,7 +125,8 @@ class AndroidFileManager(
} catch (e: Exception) { } catch (e: Exception) {
// Media File Isn't MP3 lets Convert It first // Media File Isn't MP3 lets Convert It first
if (e is InvalidDataException) { if (e is InvalidDataException) {
val convertedFilePath = songFile.absolutePath.substringBeforeLast('.') + ".temp.mp3" val convertedFilePath =
songFile.absolutePath.substringBeforeLast('.') + ".temp.mp3"
val conversionResult = mediaConverter.convertAudioFile( val conversionResult = mediaConverter.convertAudioFile(
inputFilePath = songFile.absolutePath, inputFilePath = songFile.absolutePath,
@ -138,9 +140,13 @@ class AndroidFileManager(
.setId3v2TagsAndSaveFile(trackDetails, trackDetails.outputFilePath) .setId3v2TagsAndSaveFile(trackDetails, trackDetails.outputFilePath)
addToLibrary(trackDetails.outputFilePath) addToLibrary(trackDetails.outputFilePath)
}.failure { File(convertedFilePath).delete()
throw it }.fold(
} success = {},
failure = {
throw it
}
)
} else throw e } else throw e
} }
SuspendableEvent.success(trackDetails.outputFilePath) SuspendableEvent.success(trackDetails.outputFilePath)
@ -154,16 +160,17 @@ class AndroidFileManager(
override fun addToLibrary(path: String) = methods.value.platformActions.addToLibrary(path) override fun addToLibrary(path: String) = methods.value.platformActions.addToLibrary(path)
override suspend fun loadImage(url: String, reqWidth: Int, reqHeight: Int): Picture = withContext(dispatcherIO) { override suspend fun loadImage(url: String, reqWidth: Int, reqHeight: Int): Picture =
val cachePath = imageCacheDir() + getNameURL(url) withContext(dispatcherIO) {
Picture( val cachePath = imageCacheDir() + getNameURL(url)
image = (loadCachedImage(cachePath, reqWidth, reqHeight) ?: freshImage( Picture(
url, image = (loadCachedImage(cachePath, reqWidth, reqHeight) ?: freshImage(
reqWidth, url,
reqHeight reqWidth,
))?.asImageBitmap() reqHeight
) ))?.asImageBitmap()
} )
}
private fun loadCachedImage(cachePath: String, reqWidth: Int, reqHeight: Int): Bitmap? { private fun loadCachedImage(cachePath: String, reqWidth: Int, reqHeight: Int): Bitmap? {
return try { return try {
@ -186,28 +193,32 @@ class AndroidFileManager(
} }
@Suppress("BlockingMethodInNonBlockingContext") @Suppress("BlockingMethodInNonBlockingContext")
private suspend fun freshImage(url: String, reqWidth: Int, reqHeight: Int): Bitmap? = withContext(dispatcherIO) { private suspend fun freshImage(url: String, reqWidth: Int, reqHeight: Int): Bitmap? =
try { withContext(dispatcherIO) {
val source = URL(url) try {
val connection: HttpURLConnection = source.openConnection() as HttpURLConnection val source = URL(url)
connection.connectTimeout = 5000 val connection: HttpURLConnection = source.openConnection() as HttpURLConnection
connection.connect() connection.connectTimeout = 5000
connection.connect()
val input: ByteArray = connection.inputStream.readBytes() val input: ByteArray = connection.inputStream.readBytes()
// Get Memory Efficient Bitmap // Get Memory Efficient Bitmap
val bitmap: Bitmap? = getMemoryEfficientBitmap(input, reqWidth, reqHeight) val bitmap: Bitmap? = getMemoryEfficientBitmap(input, reqWidth, reqHeight)
parallelExecutor.executeSuspending { parallelExecutor.executeSuspending {
// Decode and Cache Full Sized Image in Background // Decode and Cache Full Sized Image in Background
cacheImage(BitmapFactory.decodeByteArray(input, 0, input.size), imageCacheDir() + getNameURL(url)) cacheImage(
BitmapFactory.decodeByteArray(input, 0, input.size),
imageCacheDir() + getNameURL(url)
)
}
bitmap // return Memory Efficient Bitmap
} catch (e: Exception) {
e.printStackTrace()
null
} }
bitmap // return Memory Efficient Bitmap
} catch (e: Exception) {
e.printStackTrace()
null
} }
}
/* /*
* Parallel Executor with 2 concurrent operation at a time. * Parallel Executor with 2 concurrent operation at a time.

View File

@ -1,11 +1,18 @@
package com.shabinder.common.core_components.media_converter package com.shabinder.common.core_components.media_converter
import android.util.Log
import com.arthenica.ffmpegkit.FFmpegKit import com.arthenica.ffmpegkit.FFmpegKit
import com.arthenica.ffmpegkit.ReturnCode import com.arthenica.ffmpegkit.ReturnCode
import com.shabinder.common.models.AudioQuality import com.shabinder.common.models.AudioQuality
import com.shabinder.common.models.SpotiFlyerException import com.shabinder.common.models.SpotiFlyerException
import org.koin.dsl.bind import org.koin.dsl.bind
import org.koin.dsl.module import org.koin.dsl.module
import com.arthenica.ffmpegkit.FFprobeKit
import com.arthenica.ffmpegkit.MediaInformationSession
import kotlin.math.ceil
import kotlin.math.roundToInt
class AndroidMediaConverter : MediaConverter() { class AndroidMediaConverter : MediaConverter() {
override suspend fun convertAudioFile( override suspend fun convertAudioFile(
@ -14,10 +21,15 @@ class AndroidMediaConverter : MediaConverter() {
audioQuality: AudioQuality, audioQuality: AudioQuality,
progressCallbacks: (Long) -> Unit, progressCallbacks: (Long) -> Unit,
) = executeSafelyInPool { ) = executeSafelyInPool {
val kbpsArg = if (audioQuality == AudioQuality.UNKNOWN) "" else "-b:a ${audioQuality.kbps}k" val kbpsArg = if (audioQuality == AudioQuality.UNKNOWN) {
val mediaInformation = FFprobeKit.getMediaInformation(inputFilePath)
val bitrate = ((mediaInformation.mediaInformation.bitrate).toFloat()/1000).roundToInt()
Log.d("MEDIA-INPUT Bit", bitrate.toString())
"-b:a ${bitrate}k"
} else "-b:a ${audioQuality.kbps}k"
// -acodec libmp3lame // -acodec libmp3lame
val session = FFmpegKit.execute( val session = FFmpegKit.execute(
"-i $inputFilePath -y $kbpsArg -vn $outputFilePath" "-i $inputFilePath -y $kbpsArg -acodec libmp3lame -vn $outputFilePath"
) )
when (session.returnCode.value) { when (session.returnCode.value) {