MediaPlayer.getDuration()返回错误的持续时间

时间:2012-06-21 19:45:55

标签: android progress-bar media-player android-mediaplayer

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获得适当的最大值?

3 个答案:

答案 0 :(得分:2)

当MediaPlayer.getDuration()为mp3文件(HTC Desire C with ICS 4.0.3)返回542434 ms时,我遇到了类似的问题。 文件本身大概是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()返回正确的值。 我知道,对于那些需要播放你无法修改的文件的人来说,它无济于事,但对于那些能够修改的人来说,它应该会有所帮助。

答案 1 :(得分:0)

我几年前尝试玩演示播放器,当我在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);
        }
    });

答案 2 :(得分:0)

我遇到了类似的情况。就我而言,mPlayer.getDuration()mPlayer.getCurrentPosition()之间的时差大约为80秒。

在阅读了有关该主题的几篇帖子后,我使用第三方软件将mp3的采样率从22,000 kHz转换为44,100 kHz。转换后,getDuration()getCurrentPosition()的结果几乎相同(0.0012s恒定误差)。

以下是使用的测试:

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");

    }
});