Kotlin

[android : kotlin] MediaStore.Audio.Media로 부터 Uri를 통해 duration (노래 총 재생시간) 가져오는 방법

MediaStore.Audio.Media.DURATION를 통해 노래파일의 재생시간을 알고 싶었으나 값을 알수 없었다. 모든 노래에서 동일한 값으로 6이 넘어왔다.

val mCursorCols = arrayOf(
	MediaStore.Audio.Media._ID,
	MediaStore.Audio.Media.ARTIST,
	MediaStore.Audio.Media.TITLE,
	MediaStore.Audio.Media.ALBUM,
	MediaStore.Audio.Media.DATA,
	MediaStore.Audio.Media.ALBUM_ID,
	MediaStore.Audio.Media.DURATION
)
 fun getMediaSongList(context: Context) : ArrayList<MusicViewModel> {

            val mCursorCols = arrayOf(
                MediaStore.Audio.Media._ID,
                MediaStore.Audio.Media.ARTIST,
                MediaStore.Audio.Media.TITLE,
                MediaStore.Audio.Media.ALBUM,
                MediaStore.Audio.Media.DATA,
                MediaStore.Audio.Media.ALBUM_ID,
                MediaStore.Audio.Media.DURATION
            )
            var cur =  context.contentResolver.query(
                MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
                mCursorCols,
                null,
                null,
                null
            )

            if (cur != null && cur.moveToFirst()) {
                lateinit var title: String
                lateinit var artist: String
                lateinit var album: String
    //            - MediaStore.Audio.Albums
    //                    - MediaStore.Audio.Artists
    //                    - MediaStore.Audio.Genres
    //                    - MediaStore.Audio.Playlists
    //                    - MediaStore.Audio.Media
    //
    //                    * Nested Inteface
    //                    - MediaStore.Audio.AlbumColumns      : 앨범을 나타내는 컬럼
    //                    - MediaStore.Audio.ArtistColumns        : 연주자를 나타내는 컬럼
    //                    - MediaStore.Audio.GenresColumns     : 쟝르를 나타내는 컬럼
    //                    - MediaStore.Audio.PlaylistsColumns   : 곡목록을 나타내는 컬럼
    //                    - MediaStore.Audio.AudioColumns       : 여러개의 테이블에서 나타나는 audio file을 위한 컬럼
                val titleColumn = cur.getColumnIndex(MediaStore.Audio.Media.TITLE)
                val artistColumn = cur.getColumnIndex(MediaStore.Audio.Media.ARTIST)
                val albumColumn = cur.getColumnIndex(MediaStore.Audio.Media.ALBUM)
                val idColumn = cur.getColumnIndex(MediaStore.Audio.Media._ID) //2020.07
                val duration = cur.getColumnIndex(MediaStore.Audio.Media.DURATION)

                try {
                    do {
                        title = cur.getString(titleColumn)
                        artist = cur.getString(artistColumn)
                        album = cur.getString(albumColumn)
                        val albumIds = cur.getLong(cur.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID))
                        //Log.e("TAG", "title = $title albumIds=$albumIds]    duration: $duration")
                        val audioId = cur.getLong(idColumn)

                        val sArtworkUri = Uri.parse("content://media/external/audio/albumart")
                        val sAlbumArtUri = ContentUris.withAppendedId(sArtworkUri, albumIds)
                        //android.util.Log.i("jinsu", "sAlbumArtUri = " + sAlbumArtUri + "]");
                        val externalUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
                        val contentUri = ContentUris.withAppendedId(externalUri, audioId)




                        //                          val mediaId: String,
                        //                           val title: String,
                        //                           val subtitle: String?,
                        //                            val artist: String?,
                        //                           val albumArtUri: String,
                        //                              val contentUri: Uri,
                        //                           val duration: String

                        val musicVo = MusicViewModel(
                            audioId,
                            title,
                            "서브타이틀",
                            artist,
                            sAlbumArtUri,
                            contentUri,
                            //cur.getLong(duration)  //-1L
                            50000  //-1L
                        )
                        musicList.add(musicVo)

                    } while (cur.moveToNext())
                } catch (ee: IllegalStateException) {
                    ee.printStackTrace()
                } catch (se: SecurityException) {
                    se.printStackTrace()
                    //songsList = java.util.ArrayList<MusicVo>()
                } catch (e: Exception) {
                    e.printStackTrace()
                } finally {
                    cur?.close()
                }
            }
            return musicList
        }

    }

MediaStyle Notification을 구현할때 duration 값을 가져와 SeekBar에 설정해야함으로 필요했다.

방법은 생각보다 간단했다. 모르고 있으면 어려울뿐!!! MediaMetadataRetriever 클래스를 사용하여 duration 값을 가져올 수 있었다.

        fun getMediaDuration(context: Context, uri: Uri): Long {
            var metaRetriever:MediaMetadataRetriever = MediaMetadataRetriever()

            return try {
                //get total duration
                metaRetriever.setDataSource(context, uri)
                val duration: String =
                    metaRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)
                //val millSecond : Int =  duration
                Log.e("TAG", "#### call MyMediaSessionCallback() : duration: $duration")

                metaRetriever.release()
                duration.toLongOrNull() ?: 0
            } catch (exception: Exception) {
                0
            }
        }

이제 SeekBar를 컨트롤 할 수 있는 방법을 찾아보자!!!!!

새로운 지식을 하나씩 알아감으로 느끼는 즐거움이 참으로 오랜만에 찾아왔다.

 

착오가 있었다. 기존 방법으로 가져올 수 있다. 코딩 오류이다. 아래 코드 스니펫처럼 가져와야 한다. 위 첫번째 스니펫 코드는 값을 가져오고 있는게 아니라 인덱스 번호를 전달 받고 있었다. 

AS-IS

 val duration = cur.getColumnIndex(MediaStore.Audio.Media.DURATION)

TO-BE

val duration = cur.getLong(cur.getColumnIndex(MediaStore.Audio.AudioColumns.DURATION))

 

[build.gradle(:app)] 

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'

android {
    compileSdkVersion 29

    defaultConfig {
        applicationId "edu.kotlin.study"
        minSdkVersion 23
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }

    // For Java compilers:
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

dependencies {
    implementation fileTree(dir: "libs", include: ["*.jar"])
    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    implementation 'androidx.core:core-ktx:1.3.2'
    implementation 'androidx.appcompat:appcompat:1.2.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.4'

    implementation "androidx.media:media:1.2.0"
    implementation "androidx.recyclerview:recyclerview:1.1.0"
    //implementation "com.android.support:support-media-compat:29.+"

    // full exoplayer library
    //implementation 'com.google.android.exoplayer:exoplayer:2.11.5'
    implementation 'com.google.android.exoplayer:exoplayer-core:2.11.5'

    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'

}

[REFERENCE]

stackoverflow.com/questions/15394640/get-duration-of-audio-file/32901068

 

 

[연관 글 더보기]

[android : kotlin] 코틀린 Notification MediaStyle 사용시 SeekBar 설정 및 해제 하는 방법

[android : kotlin] 코틀린 Notification MediaStyle 사용시 앨범 자켓(이미지) setLargeIcon 설정 방법 :Bitmap , MediaMetadataCompat

[android : kotlin] 코틀린 RecyclerView 클릭시 미디어 재생 하는 방법 : MediaController ,SimpleExoPlayer

[android : kotlin] 코틀린 Notification setShowActionsInCompactView 사용 예제 : MediaStyle

[android : kotlin] 코틀린 Notification addAction 추가하는 방법(.apply) : Notification.Action.Builder

 

 

Leave a Reply

error: Content is protected !!