Search code examples
androidmetadatamedia-playeraudio-playerandroid-music-player

How to update the default song metadata?


I wanted to update the song metadata fields of Track, album, genre, artist and song cover image like Musicmatch.

I tried to look for the code to update the meta couldn't find any solutions.


Solution

  • To update the metadata of a song we can do by using ID3 tags. We can update these using Mp3Tag editor - https://github.com/aminb/id3r , MyID3() editor - https://github.com/ericfarng/jid3lib and Jaudiotagger - https://github.com/Adonai/jaudiotagger.

    Mp3Tag editor - Only Mp3 song type is supported MyID3 editor - Can edit song easily but not all field provided is updated Jaudiotagger - This supports Mp3, Flac, OggVorbis, Mp4, Aiff, Wav, Wma, Dsf audio formats It updated data without any issue

    try {
          val audioFile = AudioFileIO.read(file)
                val tag = audioFile?.tagOrCreateAndSetDefault
                 tag?.setField(FieldKey.ARTIST, binding?.tiArtist?.text?.toString())
                tag?.setField(FieldKey.ALBUM, binding?.tiAlbum?.text?.toString())
                tag?.setField(FieldKey.GENRE, binding?.tiGenre?.text?.toString())
                tag?.setField(FieldKey.TITLE, binding?.tiTrack?.text?.toString())
    
                // Handle the image setting
                try {
                        val pfd = contentResolver.openFileDescriptor(imageUri, "r") ?: return
    
                        val fis = FileInputStream(pfd.fileDescriptor)
                        val imgBytes = JavaUtils.readFully(fis)
                        val cover = AndroidArtwork()
                        cover.binaryData = imgBytes
                        cover.mimeType = ImageFormats.getMimeTypeForBinarySignature(byteArray)
                        cover.description = ""
                        cover.pictureType = PictureTypes.DEFAULT_ID
                        tag?.deleteArtworkField()
                        tag?.setField(cover)
                        fis.close()
    
                  // to do check the file write option for both internal and external card
                 // Handle the Storage Access FrameWork API if song is from SD card
                if (audioFile?.file?.let { SafUtils.isSafNeeded(it, this) } == true) {
                  // Handle writing into SD card
                  // Check if SAF permission is provided then only we can update metadata 
                 // If SAF Permission is not provided. EACCESS : Permission Denied error is displayed 
                // After the permission success then only we can update meta.
                     writeIntoSDCard()
                } else {
                    // Handle writing into internal card
                    writeInInternalStorage()
                }
             } catch (e: Exception) { }
            } catch (e: Exception) {
                // Show error on failure while writing
            } catch (e: Error) {
                // Show error on failure while writing
            }      
    

    Writing the metadata

    // After update refresh the file else the changes will not be reflected
    AudioFileIO.write(audioFile)
    MediaScannerConnection.scanFile(context, arrayOf(file?.absolutePath ?: ""), null, null)