媒体播放器、进度条
Posted
技术标签:
【中文标题】媒体播放器、进度条【英文标题】:MediaPlayer, ProgressBar 【发布时间】:2012-04-03 19:56:37 【问题描述】:这是在播放媒体时更新 ProgressBar 的正确方法吗?我想在 MediaPlayer 中会有一个回调,但我找不到它。
mediaPlayer.start();
final SeekBar progress = (SeekBar) dialog.findViewById(R.id.seekBar1);
progress.setMax(mediaPlayer.getDuration());
new CountDownTimer(mediaPlayer.getDuration(), 250)
public void onTick(long millisUntilFinished)
progress.setProgress(progress.getProgress() + 250);
public void onFinish()
.start();
最好的问候。
【问题讨论】:
【参考方案1】:就个人而言,我开始一个线程,每 200 毫秒左右检查一次 getCurrentPosition()
,直到 onCompletion()
事件被触发:
private class MediaObserver implements Runnable
private AtomicBoolean stop = new AtomicBoolean(false);
public void stop()
stop.set(true);
@Override
public void run()
while (!stop.get())
progress.setProgress(mediaPlayer.getCurrentPosition());
Thread.sleep(200);
private MediaObserver observer = null;
public void runMedia()
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener
@Override
public void onCompletion(MediaPlayer mPlayer)
observer.stop();
progress.setProgress(mPlayer.getCurrentPosition());
);
observer = new MediaObserver();
mediaPlayer.start();
new Thread(observer).start();
【讨论】:
计时器不会阻塞用户界面,所以我想它在另一个线程中。所以我想是一样的。我希望我足够聪明,能够弄清楚这些事情。 @pouzzler 倒计时计时器在另一个线程中运行,唯一的区别是它不使用实际进度。我会写一个线程示例 啊不用了,我明白了。谢谢:) 和以前一样的问题,我用了你的建议...... CountDownTimer:progress.setProgress(mediaPlayer.getCurrentPosition()); - 仍然不知道哪个是最好的 ;) 为我和我的哲学问题上床睡觉。 抱歉,我标记了另一个答案,因为它对每个人都更有用,尽管我现在会继续使用我的非 ICS 内容。【参考方案2】:看看android.widget.MediaController,它有一个进度条。
如果合适,他们会使用递归调用自身的处理程序。您可以将延迟设置为您希望更新进度条的频率。
请注意,控制器可以显示或隐藏,也可以由用户拖动,当然,视频也可以停止。这些是在另一个递归调用更新栏之前进行各种检查 (!mDragging && mShowing && mVideoView.isPlaying()
) 的原因。
protected Handler mHandler = new Handler()
@Override
public void handleMessage(Message msg)
int pos;
switch (msg.what)
// ...
case SHOW_PROGRESS:
pos = setProgress();
if (!mDragging && mShowing && mVideoView.isPlaying())
msg = obtainMessage(SHOW_PROGRESS);
sendMessageDelayed(msg, 1000 - (pos % 1000));
break;
// ...
;
要开始使用:
mHandler.sendEmptyMessage(SHOW_PROGRESS);
它会自行停止,但您应该使用以下命令取消最后一个待处理的请求:
mHandler.removeMessages(SHOW_PROGRESS);
【讨论】:
谢谢,正是我要找的东西。 @pouzzler - 不客气!查看 MediaController 类非常适合为您提供有关制作自定义控制器的想法。 第二个链接因 DMCA 删除而消失:github.com/OESF/OHA-android-4.0.1_r1.0【参考方案3】:最有效的方法是使用JRaymond的回答和EventBus
private class MediaObserver implements Runnable
private AtomicBoolean stop = new AtomicBoolean(false);
public void stop()
stop.set(true);
@Override public void run()
while (!stop.get())
try
if (player.isPlaying())
sendMsgToUI(player.getCurrentPosition(),
player.getDuration());
catch (Exception e)e.printStackTrace();
try
Thread.sleep(100);
catch (InterruptedException e) e.printStackTrace();
private MediaObserver observer = null;
public void runMedia()
observer = new MediaObserver();
new Thread(observer).start();
//handles all the background threads things for you
private void sendMsgToUI(int position)
ChangingEvent event = new ChangingEvent(position);
EventBus.getDefault().post(event);
ChangingEvent 类看起来像这样:
public class ChangingEvent
private int position;
public ChangingEvent(int position)
this.position= position;
public int getPosition()
return position;
在你的 Activity 或 Fragment 中你所要做的就是
class YouClass extends Activity
private EventBus eventBus = EventBus.getDefault();
@Override protected void onCreate(Bundle savedInstanceState)
//your code
eventBus.register(this);
//eventbus that updates UI
public void onEventMainThread(ChangingEvent event)
//seekbar or any other ui element
seekBar.setProgress(event.getPosition());
【讨论】:
我喜欢这种方法,但我认为您忘记添加循环/while,这会使 run() 被多次执行 哦,是的,感谢您注意到这一点 - 我现在会更正它。以上是关于媒体播放器、进度条的主要内容,如果未能解决你的问题,请参考以下文章