-
目录结构
-
布局文件 activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:id="@+id/root_rl"
android:layout_width="match_parent"
android:layout_height="400dp"
android:background="#000000">
<SurfaceView
android:id="@+id/surfaceView"
android:layout_width="match_parent"
android:layout_height="400dp" />
<ImageView
android:id="@+id/playOrPause"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_centerInParent="true"
android:src="@android:drawable/ic_media_play" />
<LinearLayout
android:id="@+id/control_ll"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="#55000000"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:orientation="horizontal"
android:paddingBottom="5dp">
<ProgressBar
android:id="@+id/pb_progress"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/tv_start_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/pb_progress"
android:text="00:00"
android:textColor="#ffffff" />
<TextView
android:id="@+id/tv_end_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_below="@id/pb_progress"
android:text="00:00"
android:textColor="#ffffff" />
</RelativeLayout>
</LinearLayout>
</RelativeLayout>
</merge>
- 工具类 FormatTimeUtil.java
public class FormatTimeUtil {
/**
* 将毫秒转换为00:00格式的字符串
*
* @param time
* @return
*/
public static String formatLongToTimeStr(int time) {
int minute = 0;
int second = 0;
String tmp;
minute = time / 1000 / 60;
tmp = String.valueOf(minute).length() == 2 ? minute + "" : "0" + minute + ":";
second = time / 1000 % 60;
tmp += String.valueOf(second).length() == 2 ? second + "" : "0" + second;
return tmp;
}
}
- MainActivity.java
public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback,
MediaPlayer.OnPreparedListener,
MediaPlayer.OnCompletionListener,
MediaPlayer.OnErrorListener,
MediaPlayer.OnInfoListener, View.OnClickListener,
MediaPlayer.OnSeekCompleteListener,
MediaPlayer.OnVideoSizeChangedListener {
private ImageView playOrPauseIv;
private SurfaceView videoSuf;
private MediaPlayer mPlayer;
private ProgressBar mProgressBar;
private String path;
private RelativeLayout rootViewRl;
private LinearLayout controlLl;
private TextView startTime, endTime;
private boolean isShow = false;
public static final int UPDATE_TIME = 0x0001;
public static final int HIDE_CONTROL = 0x0002;
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case UPDATE_TIME:
updateTime();
mHandler.sendEmptyMessageDelayed(UPDATE_TIME, 500);
break;
case HIDE_CONTROL:
hideControl();
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
initData();
initSurfaceView();
initPlayer();
initEvent();
}
private void initData() {
path = Environment.getExternalStorageDirectory().getPath() + "/478102.mp4";//这里写上你的视频地址
}
private void initEvent() {
playOrPauseIv.setOnClickListener(this);
rootViewRl.setOnClickListener(this);
}
private void initSurfaceView() {
videoSuf = (SurfaceView) findViewById(R.id.surfaceView);
videoSuf.setZOrderOnTop(false);
videoSuf.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
videoSuf.getHolder().addCallback(this);
}
private void initPlayer() {
mPlayer = new MediaPlayer();
mPlayer.setOnCompletionListener(this);
mPlayer.setOnErrorListener(this);
mPlayer.setOnInfoListener(this);
mPlayer.setOnPreparedListener(this);
mPlayer.setOnSeekCompleteListener(this);
mPlayer.setOnVideoSizeChangedListener(this);
try {
mPlayer.setDataSource(path);
} catch (Exception e) {
e.printStackTrace();
}
}
private void initViews() {
playOrPauseIv = (ImageView) findViewById(R.id.playOrPause);
startTime = (TextView) findViewById(R.id.tv_start_time);
endTime = (TextView) findViewById(R.id.tv_end_time);
mProgressBar = (ProgressBar) findViewById(R.id.pb_progress);
rootViewRl = (RelativeLayout) findViewById(R.id.root_rl);
controlLl = (LinearLayout) findViewById(R.id.control_ll);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
mPlayer.setDisplay(holder);
mPlayer.prepareAsync();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
@Override
public void onPrepared(MediaPlayer mp) {
startTime.setText(FormatTimeUtil.formatLongToTimeStr(mp.getCurrentPosition()));
endTime.setText(FormatTimeUtil.formatLongToTimeStr(mp.getDuration()));
mProgressBar.setMax(mp.getDuration());
mProgressBar.setProgress(mp.getCurrentPosition());
}
@Override
public void onCompletion(MediaPlayer mp) {
}
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
return false;
}
@Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
return false;
}
private void play() {
if (mPlayer == null) {
return;
}
Log.i("playPath", path);
if (mPlayer.isPlaying()) {
mPlayer.pause();
mHandler.removeMessages(UPDATE_TIME);
mHandler.removeMessages(HIDE_CONTROL);
playOrPauseIv.setVisibility(View.VISIBLE);
playOrPauseIv.setImageResource(android.R.drawable.ic_media_play);
} else {
mPlayer.start();
mHandler.sendEmptyMessageDelayed(UPDATE_TIME, 500);
mHandler.sendEmptyMessageDelayed(HIDE_CONTROL, 5000);
playOrPauseIv.setVisibility(View.INVISIBLE);
playOrPauseIv.setImageResource(android.R.drawable.ic_media_pause);
}
}
@Override
public void onSeekComplete(MediaPlayer mp) {
//TODO
}
@Override
public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.playOrPause:
play();
break;
case R.id.root_rl:
showControl();
break;
}
}
/**
* 更新播放时间
*/
private void updateTime() {
startTime.setText(FormatTimeUtil.formatLongToTimeStr(mPlayer.getCurrentPosition()));
mProgressBar.setProgress(mPlayer.getCurrentPosition());
}
/**
* 隐藏进度条
*/
private void hideControl() {
isShow = false;
mHandler.removeMessages(UPDATE_TIME);
controlLl.animate().setDuration(300).translationY(controlLl.getHeight());
}
/**
* 显示进度条
*/
private void showControl() {
if (isShow) {
play();
}
isShow = true;
mHandler.removeMessages(HIDE_CONTROL);
mHandler.sendEmptyMessage(UPDATE_TIME);
mHandler.sendEmptyMessageDelayed(HIDE_CONTROL, 5000);
controlLl.animate().setDuration(300).translationY(0);
}
}
- 清单文件 AndroidMainifest.xml中声明权限
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
- 总结
- 在surfaceCreated方法中调用MediaPlayer的setDisPlay方法和prepareAsync方法。
- 使用Handler来延时发送消息来获取MediaPlayer的currentPosition更新时间的显示。
- 使用View.animte()属性动画来显示和隐藏进度条。