From 69efe9287835c1211c71aca4bd9cf6d1b4154b25 Mon Sep 17 00:00:00 2001 From: pakka-papad Date: Fri, 8 Dec 2023 10:54:34 +0530 Subject: [PATCH 1/4] Attempt to fix: MediaMetadataRetriever.setDataSource throws IllegalArgumentException --- .../pakka_papad/data/music/SongExtractor.kt | 90 +++++++++++-------- .../com/github/pakka_papad/di/AppModule.kt | 2 + 2 files changed, 54 insertions(+), 38 deletions(-) diff --git a/app/src/main/java/com/github/pakka_papad/data/music/SongExtractor.kt b/app/src/main/java/com/github/pakka_papad/data/music/SongExtractor.kt index 6c635f3..e80ba22 100644 --- a/app/src/main/java/com/github/pakka_papad/data/music/SongExtractor.kt +++ b/app/src/main/java/com/github/pakka_papad/data/music/SongExtractor.kt @@ -6,6 +6,7 @@ import android.media.MediaMetadataRetriever import android.net.Uri import android.os.Build import android.provider.MediaStore +import com.github.pakka_papad.data.ZenCrashReporter import com.github.pakka_papad.formatToDate import com.github.pakka_papad.toMBfromB import com.github.pakka_papad.toMS @@ -20,6 +21,7 @@ import java.util.TreeMap class SongExtractor( private val scope: CoroutineScope, private val context: Context, + private val crashReporter: ZenCrashReporter, ) { private val projection = arrayOf( @@ -99,7 +101,7 @@ class SongExtractor( val dateAddedIndex = cursor.getColumnIndex(MediaStore.Audio.Media.DATE_ADDED) val dateModifiedIndex = cursor.getColumnIndex(MediaStore.Audio.Media.DATE_MODIFIED) val songIdIndex = cursor.getColumnIndex(MediaStore.Audio.Media._ID) - val dSongs = ArrayList>() + val dSongs = ArrayList>() cursor.moveToFirst() do { try { @@ -128,7 +130,7 @@ class SongExtractor( } } while (cursor.moveToNext()) - val songs = dSongs.awaitAll() + val songs = dSongs.awaitAll().filterNotNull() cursor.close() return songs } @@ -212,7 +214,7 @@ class SongExtractor( val dateAddedIndex = cursor.getColumnIndex(MediaStore.Audio.Media.DATE_ADDED) val dateModifiedIndex = cursor.getColumnIndex(MediaStore.Audio.Media.DATE_MODIFIED) val songIdIndex = cursor.getColumnIndex(MediaStore.Audio.Media._ID) - val dSongs = ArrayList>() + val dSongs = ArrayList>() val total = cursor.count var parsed = 0 cursor.moveToFirst() @@ -246,7 +248,7 @@ class SongExtractor( } } while (cursor.moveToNext()) - val songs = dSongs.awaitAll() + val songs = dSongs.awaitAll().filterNotNull() cursor.close() val albums = albumArtMap.map { (t, u) -> Album(t, ContentUris.withAppendedId(songCover, u).toString()) } return Pair(songs,albums) @@ -264,40 +266,52 @@ class SongExtractor( songId: Long, title: String, album: String, - ): Song { + ): Song? { val extractor = MediaMetadataRetriever() - extractor.setDataSource(path) - val durationMillis = extractor.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)?.toLongOrNull() ?: 0 - val sampleRate = if (Build.VERSION.SDK_INT >= 31){ - extractor.extractMetadata(MediaMetadataRetriever.METADATA_KEY_SAMPLERATE)?.toFloatOrNull() ?: 0f - } else 0f - val bitsPerSample = if (Build.VERSION.SDK_INT >= 31){ - extractor.extractMetadata(MediaMetadataRetriever.METADATA_KEY_BITS_PER_SAMPLE)?.toIntOrNull() ?: 0 - } else 0 - val song = Song( - location = path, - title = title, - album = album, - size = size.toFloat().toMBfromB(), - addedDate = addedDate.toLong().formatToDate(), - modifiedDate = modifiedDate.toLong().formatToDate(), - artist = extractor.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST)?.trim() ?: UNKNOWN, - albumArtist = extractor.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ALBUMARTIST)?.trim() ?: UNKNOWN, - composer = extractor.extractMetadata(MediaMetadataRetriever.METADATA_KEY_COMPOSER)?.trim() ?: UNKNOWN, - genre = extractor.extractMetadata(MediaMetadataRetriever.METADATA_KEY_GENRE)?.trim() ?: UNKNOWN, - lyricist = extractor.extractMetadata(MediaMetadataRetriever.METADATA_KEY_WRITER)?.trim() ?: UNKNOWN, - year = extractor.extractMetadata(MediaMetadataRetriever.METADATA_KEY_YEAR)?.toIntOrNull() ?: 0, - comment = null, - durationMillis = durationMillis, - durationFormatted = durationMillis.toMS(), - bitrate = extractor.extractMetadata(MediaMetadataRetriever.METADATA_KEY_BITRATE)?.toFloatOrNull() ?: 0f, - sampleRate = sampleRate, - bitsPerSample = bitsPerSample, - mimeType = extractor.extractMetadata(MediaMetadataRetriever.METADATA_KEY_MIMETYPE), - favourite = false, - artUri = "content://media/external/audio/media/$songId/albumart" - ) - extractor.release() - return song + var result: Song? = null + try { + extractor.setDataSource(path) + val durationMillis = extractor.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)?.toLongOrNull() ?: 0 + val sampleRate = if (Build.VERSION.SDK_INT >= 31){ + extractor.extractMetadata(MediaMetadataRetriever.METADATA_KEY_SAMPLERATE)?.toFloatOrNull() ?: 0f + } else 0f + val bitsPerSample = if (Build.VERSION.SDK_INT >= 31){ + extractor.extractMetadata(MediaMetadataRetriever.METADATA_KEY_BITS_PER_SAMPLE)?.toIntOrNull() ?: 0 + } else 0 + val song = Song( + location = path, + title = title, + album = album, + size = size.toFloat().toMBfromB(), + addedDate = addedDate.toLong().formatToDate(), + modifiedDate = modifiedDate.toLong().formatToDate(), + artist = extractor.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST)?.trim() ?: UNKNOWN, + albumArtist = extractor.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ALBUMARTIST)?.trim() ?: UNKNOWN, + composer = extractor.extractMetadata(MediaMetadataRetriever.METADATA_KEY_COMPOSER)?.trim() ?: UNKNOWN, + genre = extractor.extractMetadata(MediaMetadataRetriever.METADATA_KEY_GENRE)?.trim() ?: UNKNOWN, + lyricist = extractor.extractMetadata(MediaMetadataRetriever.METADATA_KEY_WRITER)?.trim() ?: UNKNOWN, + year = extractor.extractMetadata(MediaMetadataRetriever.METADATA_KEY_YEAR)?.toIntOrNull() ?: 0, + comment = null, + durationMillis = durationMillis, + durationFormatted = durationMillis.toMS(), + bitrate = extractor.extractMetadata(MediaMetadataRetriever.METADATA_KEY_BITRATE)?.toFloatOrNull() ?: 0f, + sampleRate = sampleRate, + bitsPerSample = bitsPerSample, + mimeType = extractor.extractMetadata(MediaMetadataRetriever.METADATA_KEY_MIMETYPE), + favourite = false, + artUri = "content://media/external/audio/media/$songId/albumart" + ) + result = song + } catch (e: Exception) { + crashReporter.logException(e) + result = null + } finally { + try { + extractor.release() + } catch (_: Exception) { } + } + return result } + + } \ No newline at end of file diff --git a/app/src/main/java/com/github/pakka_papad/di/AppModule.kt b/app/src/main/java/com/github/pakka_papad/di/AppModule.kt index 3c227f0..3ffeb72 100644 --- a/app/src/main/java/com/github/pakka_papad/di/AppModule.kt +++ b/app/src/main/java/com/github/pakka_papad/di/AppModule.kt @@ -147,11 +147,13 @@ object AppModule { @Provides fun providesSongExtractor( @ApplicationContext context: Context, + crashReporter: ZenCrashReporter, ): SongExtractor { val scope = CoroutineScope(SupervisorJob() + Dispatchers.Default) return SongExtractor( scope = scope, context = context, + crashReporter = crashReporter, ) } } \ No newline at end of file From 5638d277cfef606e08844e0c05b0e62b39c39f8c Mon Sep 17 00:00:00 2001 From: pakka-papad Date: Fri, 8 Dec 2023 11:02:33 +0530 Subject: [PATCH 2/4] Attempt to fix: Crash on invoking formatToDate --- app/src/main/java/com/github/pakka_papad/Util.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/com/github/pakka_papad/Util.kt b/app/src/main/java/com/github/pakka_papad/Util.kt index d8a22e1..6411b36 100644 --- a/app/src/main/java/com/github/pakka_papad/Util.kt +++ b/app/src/main/java/com/github/pakka_papad/Util.kt @@ -21,6 +21,7 @@ fun Float.toMBfromB(): String{ val dateFormat = SimpleDateFormat("dd/MM/yyyy", Locale.getDefault()) fun Long.formatToDate(): String { + if (this < 0) return "" val calender = Calendar.getInstance().apply { timeInMillis = this@formatToDate } From d5d954e40f2b318c2f5d738deb74f838a27e952b Mon Sep 17 00:00:00 2001 From: pakka-papad Date: Fri, 8 Dec 2023 11:27:47 +0530 Subject: [PATCH 3/4] Updated song extract statusListener logic --- .../pakka_papad/data/music/SongExtractor.kt | 37 ++++++++++++------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/com/github/pakka_papad/data/music/SongExtractor.kt b/app/src/main/java/com/github/pakka_papad/data/music/SongExtractor.kt index e80ba22..08f284d 100644 --- a/app/src/main/java/com/github/pakka_papad/data/music/SongExtractor.kt +++ b/app/src/main/java/com/github/pakka_papad/data/music/SongExtractor.kt @@ -10,6 +10,7 @@ import com.github.pakka_papad.data.ZenCrashReporter import com.github.pakka_papad.formatToDate import com.github.pakka_papad.toMBfromB import com.github.pakka_papad.toMS +import kotlinx.coroutines.CompletionHandler import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Deferred import kotlinx.coroutines.async @@ -17,6 +18,7 @@ import kotlinx.coroutines.awaitAll import java.io.File import java.io.FileNotFoundException import java.util.TreeMap +import java.util.concurrent.atomic.AtomicInteger class SongExtractor( private val scope: CoroutineScope, @@ -216,7 +218,12 @@ class SongExtractor( val songIdIndex = cursor.getColumnIndex(MediaStore.Audio.Media._ID) val dSongs = ArrayList>() val total = cursor.count - var parsed = 0 + val parsed = AtomicInteger(0) + val parseCompletionHandler = object : CompletionHandler { + override fun invoke(cause: Throwable?) { + statusListener?.invoke(parsed.incrementAndGet(), total) + } + } cursor.moveToFirst() do { try { @@ -231,19 +238,21 @@ class SongExtractor( val title = cursor.getString(titleIndex).trim() val album = cursor.getString(albumIndex).trim() albumArtMap[album] = cursor.getLong(albumIdIndex) - dSongs.add(scope.async { - getSong( - path = songPath, - size = size, - addedDate = addedDate, - modifiedDate = modifiedDate, - songId = songId, - title = title, - album = album, - ) - }) - parsed++ - statusListener?.invoke(parsed, total) + dSongs.add( + scope.async { + getSong( + path = songPath, + size = size, + addedDate = addedDate, + modifiedDate = modifiedDate, + songId = songId, + title = title, + album = album, + ) + }.apply { + invokeOnCompletion(parseCompletionHandler) + } + ) } catch (_: Exception){ } From 17d678fb189039dd46a6ce5bec2695d9b398779d Mon Sep 17 00:00:00 2001 From: pakka-papad Date: Fri, 8 Dec 2023 12:00:17 +0530 Subject: [PATCH 4/4] Updated version --- buildSrc/src/main/kotlin/Dependencies.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/Dependencies.kt b/buildSrc/src/main/kotlin/Dependencies.kt index b49c81f..a3533c3 100644 --- a/buildSrc/src/main/kotlin/Dependencies.kt +++ b/buildSrc/src/main/kotlin/Dependencies.kt @@ -129,7 +129,7 @@ object AnnotationProcessors { object AppVersion { private const val Major = 1 private const val Minor = 2 - private const val Patch = 0 + private const val Patch = 1 const val Code = Major*10000 + Minor*100 + Patch const val Name = "$Major.$Minor.$Patch" }