3

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

4

3 回答 3

2

当 MediaPlayer.getDuration() 为 mp3 文件返回 542434 毫秒(带有 ICS 4.0.3 的 HTC Desire C)时,我遇到了类似的问题。文件本身是 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() 返回了正确的值。我知道它不会帮助那些需要播放您无法修改的文件的人,但对于那些可以 - 它应该会有所帮助。

于 2012-12-13T14:46:19.000 回答
0

前段时间我尝试播放演示播放器,当我在 Android 模拟器中进行测试时,它的行为与您在问题中提到的相同,但是当我在某些真实设备中尝试时,它给了我准确的媒体持续时间值。

如果您的意图只是播放与 seekbar 同步的媒体,那么您可以执行以下操作,

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);
        }
    });
于 2014-08-05T06:00:33.823 回答
0

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

在阅读了有关该主题的几篇文章后,我使用第三方软件将mp3's sample rate 从转换22,000 kHz44,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");

    }
});
于 2017-07-21T15:34:29.760 回答