MediaPlayer.getDuration() возвращает неправильную продолжительность

Метод MediaPlayer getDuration() дает мне неправильное значение для некоторых аудиофайлов. Я думаю, что общей чертой всех этих файлов является то, что ими манипулировали с помощью Audacity или какого-либо другого инструмента для редактирования аудио. Это проблема при попытке связать прогресс MediaPlayer с индикатором выполнения.

Я пошел вперед и зарегистрировал это:

while(mPlayer.isPlaying())
    Log.i("progress/total", 
            mPlayer.getCurrentPosition() + 
            "/" + mPlayer.getDuration());

и нашел это:

I/progress/total(643): 14615/14620
I/progress/total(643): 14647/14620

Это всего две строки журнала из тысяч, но дело в том, что после того, как прогресс проходит то, что getDuration() считает общей продолжительностью песни, он просто продолжается. Поскольку MediaPlayer на самом деле может дать правильную общую продолжительность, есть ли способ использовать это, чтобы получить правильный максимум для моего ProgressBar?


person JMRboosties    schedule 21.06.2012    source источник
comment
Какая длина песни на самом деле?   -  person ghostbust555    schedule 22.06.2012
comment
В каком формате файлы? Многие игроки сообщают о плохих значениях для MP3 с переменным битрейтом. Попробуйте снова экспортировать их с постоянным битрейтом и посмотрите, исправит ли это проблему.   -  person Geobits    schedule 22.06.2012
comment
Да, это MP3. Файлы будут выбраны пользователями с устройств, поэтому я ищу решение, которое не требует повторного экспорта файлов. Я подумал, что, поскольку MediaPlayer может получить полную продолжительность песни, если он воспроизведет ее до конца (getCurrentPosition() не привязан к getDuration()), я мог бы найти хакерский способ исправить индикатор выполнения. Мысли?   -  person JMRboosties    schedule 22.06.2012


Ответы (3)


У меня была аналогичная проблема, когда MediaPlayer.getDuration() возвращал 542434 мс для файла mp3 (HTC Desire C с ICS 4.0.3). Сам файл был около 89 секунд, разница слишком большая. Я проверил содержимое файла mp3 и увидел какой-то странный xml, например:

<?xpacket begin="п»ї" id="W5M0MpCehiHzreSzNTczkc9d"?>
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 4.2.2-c063 53.351735, 2008/07/22-18:04:26        ">

После сохранения этого файла как нового этот xml был удален, а getDuration() вернул правильное значение. Я знаю, что это не поможет тем, кому нужно проигрывание файлов, которые нельзя модифицировать, но тем, кому можно - должно помочь.

person Artem Svystun    schedule 13.12.2012
comment
Мы использовали MP3, экспортированные через Adobe Soundbooth; преобразование их в Ogg в Audacity, кажется, теперь дает правильную продолжительность. - person Paul Lammertsma; 14.12.2012

Некоторое время назад я пытался воспроизвести демо-плеер, когда я тестировал в эмуляторе Android, его поведение было таким же, как вы упомянули в своем вопросе, но когда я попробовал на каком-то реальном устройстве, это дало мне точное значение продолжительности мультимедиа.

Если вы намерены воспроизводить только синхронизацию мультимедиа с панелью поиска, вы можете сделать что-то вроде ниже,

if (!mediaPlayer.isPlaying())
mediaPlayer.start();

handler.post(new SeekbarRefresh(seekbar));

//Class to update progress of seekbar according to music player 
private class SeekbarRefresh implements Runnable {
    SeekBar seekBar;

    public SeekbarRefresh(SeekBar seekBar, ImageView imageView) {
        this.seekBar = seekBar;
    }

    @Override
    public void run() {

        if (mediaPlayer != null) {
            if (mediaPlayer.getDuration() > 0) {
                int currentDuration = mediaPlayer.getCurrentPosition();
                seekBar.setProgress(currentDuration);
                if (mediaPlayer.isPlaying()){
                    handler.post(this);
                    isAudioPlaying = true;
                     }
                else {
                    handler.removeCallbacks(this);
                    isAudioPlaying = false;
                }
            }
        }
    }
}

    seekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {

        }
        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {

        }
        @Override
        public void onProgressChanged(SeekBar seekBar, int progress,
                boolean fromUser) {

            mediaPlayer.seekTo(progress);
        }
    });
person dharam    schedule 05.08.2014

Я столкнулся с похожей ситуацией. В моем случае разница во времени между mPlayer.getDuration() и mPlayer.getCurrentPosition() составляла около 80 секунд.

Прочитав несколько сообщений на эту тему, я использовал стороннее программное обеспечение для преобразования частоты дискретизации mp3 из 22,000 kHz в 44,100 kHz. После преобразования результаты getDuration() и getCurrentPosition() почти одинаковы (постоянная ошибка 0,0012 с).

Вот используемый тест:

dur = mp.getDuration();
Log.d("dur", dur + " <- getDuration");
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
    public void onCompletion(MediaPlayer mp) {
        // finish current activity
       Log.d("dur", mp.getCurrentPosition() + " <- getCurrentPostion");

    }
});
person Idan    schedule 21.07.2017