Search code examples
androidmetadataandroid-contentprovider

How to get audio file metadata from custom content provider?


I have an app that serves as a content provider that stores .mp3 files.

F.e. content://.../player/audio.mp3

How can i get the metadata of these files?


When I stored the data in file:///.../player/audio.mp3 I used MediaMetadataRetriever() so the code looked like this:

    fun metadataDuration(uri: Uri): Long {
        val retriever = MediaMetadataRetriever()
        retriever.setDataSource(context, uri)
        return retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)!!.toLong()
    }

But if I try to use uri as content://.../player/audio.mp3 I get errors:

W/System.err:     at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:188)
W/System.err:     at android.database.DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(DatabaseUtils.java:151)
W/System.err:     at android.content.ContentProviderProxy.openTypedAssetFile(ContentProviderNative.java:705)
W/System.err:     at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1687)
W/System.err:     at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:1503)
W/System.err:     at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:1420)
W/System.err:     at android.media.MediaMetadataRetriever.setDataSource(MediaMetadataRetriever.java:171)

Solution

  • In my case, I couldn't use MediaDataRetriever / FFmpegMediaMetadataRetriever with Content Provider URIs:

    fun metadataDuration(uri: Uri): Long {
            val retriever = MediaMetadataRetriever()
            retriever.setDataSource(context, uri)
            return retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)!!.toLong()
        }
    

    so this code didn't work, as I said in the question.


    The only thing I can do with each file from the Content Provider is to read the ByteArray of the file.

    Solution:

    I found a way to create file and get the File Descriptor , so I can use MediaDataRetriever / FFmpegMediaMetadataRetriever

    I used: MemoryFile

    val newMemoryFile = MemoryFile(memoryFileName, fileContent.size)
    newMemoryFile.writeBytes(fileContent, 0, 0, fileContent.size)
    val fd = getFileDescriptor(newMemoryFile)
    val mmr = FFmpegMediaMetadataRetriever()
    mmr.setDataSource(fd)
    val duration = mmr.extractMetadata(FFmpegMediaMetadataRetriever.METADATA_KEY_DURATION).toLong()
    mmr.release()
    newMemoryFile.close()
    

    To get File Descriptor I used this code: MemoryFileGetFileDescriptor