activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<SurfaceView
android:id="@+id/sv"
android:layout_width="match_parent"
android:layout_height="300dp" />
<SeekBar
android:id="@+id/seekbar"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:text="00:00/00:00"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/play"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="播放"/>
<Button
android:id="@+id/pause"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="暫停"/>
<Button
android:id="@+id/stop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="停止"/>
<Button
android:id="@+id/replay"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="重播"/>
</LinearLayout>
</LinearLayout>
MainActivity.class
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
/**SurfaceView內部採用雙緩存機制,它會緩存視頻中的流數據,將數據進行渲染之後推送到屏幕上做顯示。
簡單來講,他就是一個顯示視頻的屏幕。*/
private SurfaceView sv;
private SurfaceHolder holder;
private SeekBar seekbar;
private MediaPlayer player;
private TextView time;
private Button play;
private Button pause;
private Button stop;
private Button replay;
private int duration;
private boolean isUpdateBar;
// 獲取視頻路徑
String path = Environment.getExternalStorageDirectory() + "/Movies/Uptown Funk.mp4";
// 播放器的幾個狀態,我們可以通過狀態碼來判斷
public static final int PLAYING = 1; // 播放狀態
public static final int PAUSING = 2; // 暫停狀態
public static final int STOPPING = 3; // 停止狀態
private int CURRENT = 0; // 當前狀態
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sv = findViewById(R.id.sv);
seekbar = findViewById(R.id.seekbar);
play = findViewById(R.id.play);
pause = findViewById(R.id.pause);
stop = findViewById(R.id.stop);
replay = findViewById(R.id.replay);
time = findViewById(R.id.time);
play.setOnClickListener(this);
pause.setOnClickListener(this);
stop.setOnClickListener(this);
replay.setOnClickListener(this);
holder = sv.getHolder();
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); // 設置緩衝
seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
//開始拖動seekbar的時候停止更新seekbar
stopSeekBar();
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
//停止拖動seekbar的時候定位到相應的位置,並且開始更新seekbar
if(player != null) {
if(CURRENT == PLAYING) {
player.seekTo(seekBar.getProgress());
updateSeekBar();
}
}
}
});
}
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.play:
try {
if (player != null) {
if (CURRENT == PLAYING) { //當前是播放狀態
return;
} else if (CURRENT == PAUSING) { // 當前是暫停狀態
player.seekTo(seekbar.getProgress());
player.start();
CURRENT = PLAYING;
updateSeekBar();
return;
}
}
if (CURRENT == 0 || CURRENT == STOPPING) { //如果是最開始的狀態或者是停止狀態
// 創建一個播放器對象
player = new MediaPlayer();
// 設置路徑
player.setDataSource(path);
// 準備
player.prepare();
// 獲取視頻最大的時長(毫秒爲單位)
duration = player.getDuration();
// 設置seekBar的最大值
seekbar.setMax(duration);
// 格式化最大時間
String lastTime = formatTime(duration);
time.setText("00:00/" + lastTime);
player.seekTo(seekbar.getProgress());
// 視頻開始播放
player.start();
// 更新seekBar
updateSeekBar();
// 設置輸出畫面
player.setDisplay(holder);
CURRENT = PLAYING;
}
} catch(IOException e){
e.printStackTrace();
}
break;
case R.id.pause: // 暫停
if(player != null && CURRENT == PLAYING) {
player.pause();
stopSeekBar();
CURRENT = PAUSING;
}
break;
case R.id.stop: // 停止播放
if(player != null) {
if(CURRENT == PLAYING || CURRENT == PAUSING) {
stopSeekBar();
seekbar.setProgress(0);
time.setText("00:00/"+formatTime(duration));
player.stop(); // 播放器處於停止狀態 所有設置都清零
player.release(); // 釋放資源
CURRENT = STOPPING;
}
}
break;
case R.id.replay: // 重播
if(player != null) {
try{
player.reset(); // 播放器空閒狀態 要想播放必須重新設置路徑還要進入準備狀態
player.setDataSource(path);
player.prepare(); // 準備狀態
player.start();
CURRENT = PLAYING;
}catch (IOException e) {
e.printStackTrace();
}
}
break;
default:
break;
}
}
//更新進度條
private void updateSeekBar(){
isUpdateBar = true;
new Thread(new Runnable() {
@Override
public void run() {
while(isUpdateBar) {
// 每秒更新一次
SystemClock.sleep(1000);
if(player != null && CURRENT == PLAYING){
seekbar.setProgress(player.getCurrentPosition());
// 在主線程中更新UI
runOnUiThread(new Runnable() {
@Override
public void run() {
String current = formatTime(player.getCurrentPosition()); // 播放進度
String durationString = formatTime(duration); // 最大時間
time.setText(current + "/" + durationString);
}
});
}
}
}
}).start();
}
private String formatTime(int duration) {
int second = duration / 1000; // 先轉換成總秒數 270s
int minute = second / 60; // 在轉換成總分鐘 4
second = second - minute * 60; // 轉換成秒位置上的秒數 30s
StringBuilder sb = new StringBuilder();
sb.append(minute > 10 ? minute + "" : "0" + minute); // 04
sb.append(":");
sb.append(second > 10 ? second + "" : "0" + second);// 04:30
return sb.toString();
}
private void stopSeekBar(){
isUpdateBar = false;
}
}
媒體控制器
MainActivity.class
public class MainActivity extends AppCompatActivity {
/**videoView播放器*/
private VideoView mVideoView;
/**媒體控制器*/
private MediaController mController;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 設置窗口格式爲半透明
getWindow().setFormat(PixelFormat.TRANSLUCENT);
setContentView(R.layout.activity_main);
// 綁定videoView控件
mVideoView = findViewById(R.id.video_view);
// 創建MediaController對象
mController = new MediaController(this);
// 準備播放文件
File video = new File(Environment.getExternalStorageDirectory()+"/Movies/小城大事-張學友.mp4");
// 如果文件存在
if(video.exists()) {
mVideoView.setVideoPath(video.getPath());
// 設置VideoView與Controller建立關聯
mVideoView.setMediaController(mController);
// 設置controller和videoView建立關聯
mController.setMediaPlayer(mVideoView);
//讓VideoView獲取焦點
mVideoView.requestFocus();
}
}
}