序言
以前也写过视频的全屏半屏的播放,参考地址。但是是用于直播,没有seekbar这样的点播功能,现在我们加上去。
效果图
麻雀虽少,五脏俱全嘛。
一. 布局文件
这里我们把显示 播放时间/总时间 弄成一个textview,你们实际中可以分开来,仅供参考。
<SeekBar
style="?android:attr/progressBarStyleHorizontal"
android:progressDrawable="@drawable/bg_seekbar_progress_drawable"
android:thumb="@null"
android:id="@+id/seekbar"
android:layout_width="match_parent"
android:layout_marginRight="150dp"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:layout_marginLeft="40dp"
/>
<TextView
android:id="@+id/tv_time"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:layout_gravity="bottom|right"
android:layout_marginRight="40dp"
android:text="00:00/00:00"
/>
二.seekbar的监听
即,我们拖动seekbar的时候,播放器会调到指定的视频进度。
这里介绍下mediaplayer的几个方法:
1. mediaplayer.seekTo(int ) 跳转到指定的进度
2. mMediaPlayer.getCurrentPosition() 获取当前进度 单位ms
3. mMediaPlayer.getDuration(); 获取视频总时长,单位ms
seekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (mMediaPlayer != null && fromUser) {
mMediaPlayer.seekTo(progress);
int currentPosition = mMediaPlayer.getCurrentPosition();
int duration = mMediaPlayer.getDuration();
Log.d("423", "current---" + currentPosition + "--duration--" + duration);
tv_time.setText(toTime(currentPosition) + "/" + toTime(duration));
}
}
});
一个转换时间的工具类
/**
* 将时长毫秒转成 00:00 格式
*
* @param duration
* @return
*/
private String toTime(int duration) {
if (duration / 1000 % 60 < 10) {
return duration / 1000 / 60 + ":0" + duration / 1000 % 60;
}
return duration / 1000 / 60 + ":" + duration / 1000 % 60;
}
三、seekbar随着视频播放不断更新进度
我们再 mediaplyer的onprepared里面监听
class PreparedListener implements OnPreparedListener {
int postSize;
@Override
public void onPrepared(MediaPlayer mp) {
Log.e("onPrepared", "----onPrepared");
pb_progressbar.setVisibility(View.GONE); // 取消dialog
int max = mMediaPlayer.getDuration();
tv_time.setText(toTime(max));
Log.d("716","max:"+max);
seekBar.setMax(max);
btn_play_video.setBackgroundResource(R.drawable.icon_topause);
if (mMediaPlayer != null) {
ISPLAYING = true;
mMediaPlayer.start(); // 播放
mHandler.sendMessageDelayed(mHandler.obtainMessage(100), 3000);
mHandler.sendEmptyMessage(101);
} else {
return;
}
}
}
这里就一行代码:mhandler.sendEmptyMessage(101)。
原理上就是不断的getcurrentPosition 来显示时间。
在这里我们利用handler不断的发信息处理,我这里睡了500ms。
case 101:
currentPosition = mMediaPlayer.getCurrentPosition();
seekBar.setProgress(currentPosition);
tv_time.setText(toTime(currentPosition) + "/" + toTime(mMediaPlayer.getDuration()));
msg=obtainMessage(101);
sendMessageDelayed(msg, 500);
参考了VideoView源码,它发送的是如下:
这个是android.widget.MediaController.java
private final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
int pos;
switch (msg.what) {
case FADE_OUT:
hide();
break;
case SHOW_PROGRESS:
pos = setProgress();
if (!mDragging && mShowing && mPlayer.isPlaying()) {
msg = obtainMessage(SHOW_PROGRESS);
sendMessageDelayed(msg, 1000 - (pos % 1000));
}
break;
}
}
};
private int setProgress() {
if (mPlayer == null || mDragging) {
return 0;
}
int position = mPlayer.getCurrentPosition();
int duration = mPlayer.getDuration();
if (mProgress != null) {
if (duration > 0) {
// use long to avoid overflow
long pos = 1000L * position / duration;
mProgress.setProgress( (int) pos);
}
int percent = mPlayer.getBufferPercentage();
mProgress.setSecondaryProgress(percent * 10);
}
if (mEndTime != null)
mEndTime.setText(stringForTime(duration));
if (mCurrentTime != null)
mCurrentTime.setText(stringForTime(position));
return position;
}
参考videoview这样基本就搞定了。
快进
if(mMediaPlayer!=null){
int currentPosition = mMediaPlayer.getCurrentPosition();
mMediaPlayer.seekTo(currentPosition+5000);
}
快退
if(mMediaPlayer!=null){
int currentPosition = mMediaPlayer.getCurrentPosition();
mMediaPlayer.seekTo(currentPosition-5000);
}
附上源码下载地址