播放音频文件时平滑增加进度条

时间:2014-03-18 10:27:42

标签: android android-progressbar

我在我的应用程序中播放不同大小的音频文件,在播放音频时,进度条应该顺利进行,但进度条采用随机大小步骤。

我正在使用以下代码:

 mp = new MediaPlayer(); 
 mp.setDataSource("audio file path");
 mp.prepare();
 mp.start();
 pb.setMax(mp.getDuration());
            new AsyncTask<Void, Integer, Void>() {
                @Override
                protected Void doInBackground(Void... params) {
                    while(mp.isPlaying())
                    {
                     publishProgress(mp.getCurrentPosition);
                    }
                    return null;
                }
                 protected void onProgressUpdate(Integer... progress) {
                     pb.setProgress(progress[0]);
                 }
                @Override
                protected void onPostExecute(Void result) {
                    super.onPostExecute(result);
                    mp.stop();
                    mp.release();
                }
            }.execute();

有没有办法顺利增加进度条?

5 个答案:

答案 0 :(得分:2)

请检查此步骤

第1步: 使用MediaPlayer.getDuration()

获取音频持续时间

第2步: 设置ProgressBar进度最大值价值与第1步的价值

第3步:

在使用处理程序播放媒体时,定期从MediaPlayer.getCurrentPosition()更新进度条。

所以代码就像这样

MediaPlayer mMediaPlayer = new MediaPlayer();
    final SeekBar mSeelBar = new SeekBar(this);
    final int duration = mMediaPlayer.getDuration();
    final int amountToUpdate = duration / 100;
    Timer mTimer = new Timer();
    mTimer.schedule(new TimerTask() {

        @Override
        public void run() {
            runOnUiThread(new Runnable() {

                @Override
                public void run() {
                    if (!(amountToUpdate * mSeelBar.getProgress() >= duration)) {
                        int p = mSeelBar.getProgress();
                        p += 1;
                        mSeelBar.setProgress(p);
                    }
                }
            });
        };
    }, amountToUpdate);

我按照this链接获取代码

答案 1 :(得分:2)

这是我的媒体播放器创建,只需查看它。

  public TextView songName,startTimeField,endTimeField;
   private MediaPlayer mediaPlayer;
   private double startTime = 0;
   private double finalTime = 0;
   private Handler myHandler = new Handler();;
   private int forwardTime = 5000; 
   private int backwardTime = 5000;
   private SeekBar seekbar;
   private ImageButton playButton,pauseButton;
   public static int oneTimeOnly = 0;
   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      songName = (TextView)findViewById(R.id.textView4);
      startTimeField =(TextView)findViewById(R.id.textView1);
      endTimeField =(TextView)findViewById(R.id.textView2);
      seekbar = (SeekBar)findViewById(R.id.seekBar1);
      playButton = (ImageButton)findViewById(R.id.imageButton1);
      pauseButton = (ImageButton)findViewById(R.id.imageButton2);
      songName.setText("song.mp3");
      mediaPlayer = MediaPlayer.create(this, R.raw.song);
      seekbar.setClickable(false);
      pauseButton.setEnabled(false);

   }

   @TargetApi(Build.VERSION_CODES.GINGERBREAD) public void play(View view){
   Toast.makeText(getApplicationContext(), "Playing sound", 
   Toast.LENGTH_SHORT).show();
      mediaPlayer.start();
      finalTime = mediaPlayer.getDuration();
      startTime = mediaPlayer.getCurrentPosition();
      if(oneTimeOnly == 0){
         seekbar.setMax((int) finalTime);
         oneTimeOnly = 1;
      } 

      endTimeField.setText(String.format("%d min, %d sec", 
         TimeUnit.MILLISECONDS.toMinutes((long) finalTime),
         TimeUnit.MILLISECONDS.toSeconds((long) finalTime) - 
         TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.
         toMinutes((long) finalTime)))
      );
      startTimeField.setText(String.format("%d min, %d sec", 
         TimeUnit.MILLISECONDS.toMinutes((long) startTime),
         TimeUnit.MILLISECONDS.toSeconds((long) startTime) - 
         TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.
         toMinutes((long) startTime)))
      );
      seekbar.setProgress((int)startTime);
      myHandler.postDelayed(UpdateSongTime,100);
      pauseButton.setEnabled(true);
      playButton.setEnabled(false);
   }

   private Runnable UpdateSongTime = new Runnable() {
      @TargetApi(Build.VERSION_CODES.GINGERBREAD) public void run() {
         startTime = mediaPlayer.getCurrentPosition();
         startTimeField.setText(String.format("%d min, %d sec", 
            TimeUnit.MILLISECONDS.toMinutes((long) startTime),
            TimeUnit.MILLISECONDS.toSeconds((long) startTime) - 
            TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.
            toMinutes((long) startTime)))
         );
         seekbar.setProgress((int)startTime);
         myHandler.postDelayed(this, 100);
      }
   };
   public void pause(View view){
      Toast.makeText(getApplicationContext(), "Pausing sound", 
      Toast.LENGTH_SHORT).show();

      mediaPlayer.pause();
      pauseButton.setEnabled(false);
      playButton.setEnabled(true);
   }    
   public void forward(View view){
      int temp = (int)startTime;
      if((temp+forwardTime)<=finalTime){
         startTime = startTime + forwardTime;
         mediaPlayer.seekTo((int) startTime);
      }
      else{
         Toast.makeText(getApplicationContext(), 
         "Cannot jump forward 5 seconds", 
         Toast.LENGTH_SHORT).show();
      }

   }
   public void rewind(View view){
      int temp = (int)startTime;
      if((temp-backwardTime)>0){
         startTime = startTime - backwardTime;
         mediaPlayer.seekTo((int) startTime);
      }
      else{
         Toast.makeText(getApplicationContext(), 
         "Cannot jump backward 5 seconds",
         Toast.LENGTH_SHORT).show();
      }

   }

答案 2 :(得分:1)

将进度条的最大尺寸设置为高范围...如果您将进度条设置为在1到最大值100之间递增,那么而不是使用100作为最大使用1000就位。这是我的建议。因为我发现你的代码工作正常。

答案 3 :(得分:0)

您可以使用以下逻辑使其更流畅。

  1. 将进度条的当前值和最新进度值存储为成员。

  2. 调用onProgressUpdate方法时更新后者。

  3. 在计时器中,将此逻辑定期执行。

    if (currentValue < latestProgress) {
        currentValue++;
        pb.setProgress(currentValue);
    }
    

    请注意,它会慢慢朝着它的目标值前进。

  4. 希望这有帮助。

答案 4 :(得分:0)

虽然建议在播放时使用Handler跟踪Audio的当前位置是唯一正确的方法。但是,MediaPlayer.getCurrentPosition() 对于短音频(比如大约 1 秒)不是非常精确;为了让生活更轻松,我编写了一个 Utils 类来支持此目的,使用 CountDownTimer

链接演示: https://github.com/mttdat/utils