【问题标题】:Android MediaPlayer getCurrentPosition() causes audio stutterAndroid MediaPlayer getCurrentPosition() 导致音频卡顿
【发布时间】:2012-09-29 09:54:49
【问题描述】:

我正在使用 SeekBar 来显示音频文件的进度并搜索到某个时间。为了更新,我使用了一个 Runnable,它每秒左右在 MediaPlayer 上调用 getCurrentPosition()。每次发生这种情况时,音频都会出现少量延迟。由于我经常调用它,所以在演奏某些东西时我会变得非常明显的口吃。如果相关,我使用的是 setAudioStreamType(AudioManager.STREAM_MUSIC),文件格式是 mp4,带有 AAC 音频(无视频),我使用的是 Android 2.3.4。有没有办法使用 getCurrentPosition() 获得良好的音频,还是我必须实现自己的进度计算?

Runnable:

private Runnable mUpdateTask = new Runnable(){

    @Override
    public void run() {
        mSeekBar.setProgress((int) (mPlayer.getCurrentPosition() * 100 / mArrayAdapter.getRecording(mPlayingId).mDuration));
        mHandler.postDelayed(mUpdateTask, 999);
    }
};

【问题讨论】:

  • 我已经为 VideoView 完成了该操作,您可以查看 here

标签: android audio media-player


【解决方案1】:

我遇到了同样的问题或类似的问题。

当我在 TimerTask 中使用mMediapPlayer.getCurrentPosition() 更新 SeekBar 时,我听到了类似回声的声音问题,但实际上问题不存在..

问题是我还使用 SeekBar OnSeekBarChangeListener 进行手动搜索,但发生的情况是从 TimerTask 更新 seekBar 也触发了侦听器,这导致了 mp.seekTo(progress) 这导致 mp 返回又是那个位置。。

我已按照此处的建议使用 fromUser 参数修复它,仅在手动更改 seekBar 时才进行搜索。

这是我的示例代码:

定时器任务:

public void initializeTimerTask() {

    mTimerTask = new TimerTask() {

        public void run() {

            int progress = mp.getCurrentPosition()/1000;
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    mSeekBar.setProgress(progress);
                    tvDuration.setText(DateUtils.formatElapsedTime(progress));
                }
            });

        }
    };
}

听众:

 mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
            if(mp != null && fromUser){
                mp.seekTo(progress * 1000);
            }
        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {

        }

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {

        }
    });

【讨论】:

  • 我的问题正是..它让我发疯。谢谢。
【解决方案2】:

你可以这样做:

private Runnable mUpdateTask = new Runnable(){

    @Override
    public void run() 
  {
        mSeekBar.setProgress(mMediapPlayer.getCurrentPosition());       
        mHandler.postDelayed(mUpdateTask, 999);
    }
};

您也可以按如下方式应用搜索栏进度更改监听器:

mSeekBar.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) 
                {
                    if (fromUser) 
                    {
                        int secProgress = seekBar.getSecondaryProgress();
                                if (secProgress> progress) 
                                {
                                    mMediapPlayer.seekTo(progress);
                                } 
                                else
                                {   
                                    seekBar.setProgress(mSeekBar.getProgress());
                                }
                    }

                }               
            });
            mMediapPlayer.setOnBufferingUpdateListener(new OnBufferingUpdateListener() 
            {

                    @Override
                    public void onBufferingUpdate(MediaPlayer mp, int percent) 
                    {
                        mSeekBar.setSecondaryProgress((mSeekBar.getMax()/100)*percent);

                    }
                });

【讨论】:

    【解决方案3】:

    我用这种方法计算进度'

    public static int getProgressPercentage(long currentDuration,
                long totalDuration) {
            Double percentage = (double) 0;
    
            long currentSeconds = (int) (currentDuration / 1000);
            long totalSeconds = (int) (totalDuration / 1000);
    
            // calculating percentage
            percentage = (((double) currentSeconds) / totalSeconds) * 100;
    
            // return percentage
            return percentage.intValue();
        }
    

    注意:mPlayer.getCurrentPosition() 不准确。报告了一些错误。我遇到了当前位置高于 totalDuration 的问题。

    【讨论】:

    • 我已经实现了类似的东西,但由于我有暂停和搜索,所以有点复杂。
    • 你能告诉我什么必须传递给方法吗? IE。如何获取 currentDuration?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多