Home » Java » java – Get duration of an audio file – Android-Exceptionshub

java – Get duration of an audio file – Android-Exceptionshub

Posted by: admin February 25, 2020 Leave a comment

Questions:

I am trying to the duration of my audio files by clicking on them through a ListView. In this list view I am correctly displaying the names on them and I am able to play them, but I would like to know its duration.

I have looked for different questions in Stackoverflow which actually seem to answer this question but I am not truly able to do it so I will leave here my attempt. I have tried to follow this answer but it does not work so I assume that I am falling getting or understanding the Uri.

The file is stored at /raw/

JAVA – 1st attempt

listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            // play desired audio
            Field[] fields = R.raw.class.getFields();
            if(soundMap.selectedEncoder != null) {
                //Log.d(TAG,  String.valueOf(soundMap.getX()) + " " + String.valueOf(soundMap.getY()));
                soundMap.selectedEncoder.play(position, audioFiles[position]);

                // Get duration of the audio file
                Uri uri = Uri.parse("/raw/"+fields[position].getName());
                MediaMetadataRetriever mmr = new MediaMetadataRetriever();
                mmr.setDataSource(getApplicationContext(), uri);
                String durationStr = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
                //int audioFileDuration = Integer.parseInt(durationStr);

            }
        }
    });

The audios are stored at the raw folder. I have also tried to add .mp3 to the uri

ERROR

E/AndroidRuntime: FATAL EXCEPTION: main
Process: myapp, PID: 26303
java.lang.IllegalArgumentException

JAVA – 2nd attempt

File audioFile = new File("/raw/"+fields[position].getName()+ ".mp3");
                    mmr.setDataSource(context, Uri.fromFile(audioFile));
                    String time = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
                    long timeInMillisec = Long.parseLong(time );

EDIT – 3rd attempt
In the end I have used MediaPlayer

AssetFileDescriptor afd = context.getResources().openRawResourceFd(R.raw.andthenturnleft);
                if (afd == null) return;
                try {
                    mediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
                } catch (IOException e) {
                    e.printStackTrace();
                }

                int audioFileDuration = mediaPlayer.getDuration();
                /*try {

and I get the duration of the file. Nevertheless, first I get the following error:

E/MediaPlayerNative: Attempt to call getDuration in wrong state:
mPlayer=0xf6f4e7a0, mCurrentState=2

I assume that the error is generated because during the first attempt to get the duration the MediaPlayer is not ready yet. I would like to stop the code until is ready. Nevertheless, in the end I get audioFileDuration with a value of 24 which is not possible because it should return the value in milliseconds and the file is 2seconds long.

4th attempt

String path = context.getFilesDir().getAbsolutePath();
                try {
                    mediaPlayer.setDataSource(path + fields[position].getName() + ".mp3");
                } catch (IOException e) {
                    e.printStackTrace();
                }

                int audioFileDuration = mediaPlayer.getDuration();

the problem is this case is that I get a value of 0 because it does not find the file

open failed: ENOENT (No such file or directory)

How could I properly get the path of the file?

SOLVED
I have posted my own solution. I just needed to find a new way to set the path of the file and I finally managed to do it.

How to&Answers:
    implementation 'com.github.wseemann:FFmpegMediaMetadataRetriever:1.0.14'

            FFmpegMediaMetadataRetriever metadataRetriever = new FFmpegMediaMetadataRetriever();
                metadataRetriever = new FFmpegMediaMetadataRetriever();
                metadataRetriever.setDataSource(url);
        LogMessage.v("1::Duration" + retriever.extractMetadata(FFmpegMediaMetadataRetriever.METADATA_KEY_DURATION));

Answer:

At the end I used another way to get the path of the file and I was able to solve this error. I copy here the code that I used:

 Uri mediaPath = Uri.parse("android.resource://com.package.name/" + R.raw.audioname);
                mmr.setDataSource(context, mediaPath);
                String duration = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
                Log.d(TAG, duration);
                mmr.release();