2019独角兽企业重金招聘Python工程师标准>>>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/widget34"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
tools:context=".MainActivity" >
<EditText
android:id="@+id/et_src"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="请输入资源路径……"
android:textSize="18sp" />
<SeekBar
android:id="@+id/seekBar_progress"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<LinearLayout
android:id="@+id/widget35"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<Button
android:id="@+id/btn_play"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="播放" />
<Button
android:id="@+id/btn_pause"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="暂停" />
<Button
android:id="@+id/btn_replay"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="01"
android:text="重播" />
<Button
android:id="@+id/btn_stop"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="停止" />
</LinearLayout>
<SurfaceView
android:id="@+id/sfView"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
package com.pas.video.play;
import java.io.File;
import java.util.Timer;
import java.util.TimerTask;
import com.pas.video.play.R;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.os.Bundle;
import android.os.Environment;
import android.app.Activity;
import android.view.Menu;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.Toast;
public class MainActivity extends Activity implements OnClickListener {
private EditText et_mediaSrc;
private Button bt_play, bt_pause, bt_replay, bt_stop;
private SurfaceView sv;
private SeekBar seekBar_progress;
private Timer timer;
private TimerTask timerTask;
/**
* 互斥变量 解决进度条手动改变 与进度条线程中run方法自动改变之间的冲突
*/
private Boolean ischanging = false;
// 媒体对象
private MediaPlayer mediaPlayer;
private int currentPosition = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et_mediaSrc = (EditText) findViewById(R.id.et_src);
sv = (SurfaceView) findViewById(R.id.sfView);
seekBar_progress = (SeekBar) findViewById(R.id.seekBar_progress);
seekBar_progress.setOnSeekBarChangeListener(new MySeekListener());
// 设置SurfaceView不维护自己的缓冲区,而是等待屏幕的渲染引擎将内容推送用户界面
// 低版本必须 4.0之上无需设置
sv.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
// 应用最小化后的处理与恢复处理
sv.getHolder().addCallback(new Callback() {
// 最小化后 系统自动销毁surfaceview中的holder对象
// 保存进度
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
System.out.println("Holder销毁");
if (mediaPlayer != null && mediaPlayer.isPlaying()) {
currentPosition = mediaPlayer.getCurrentPosition();
stop();
}
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
System.out.println("Holder创建");
if (currentPosition > 0) {
play(currentPosition);
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
System.out.println("Holder大小改变");
}
});
bt_play = (Button) findViewById(R.id.btn_play);
bt_pause = (Button) findViewById(R.id.btn_pause);
bt_replay = (Button) findViewById(R.id.btn_replay);
bt_stop = (Button) findViewById(R.id.btn_stop);
bt_play.setOnClickListener(this);
bt_pause.setOnClickListener(this);
bt_replay.setOnClickListener(this);
bt_stop.setOnClickListener(this);
et_mediaSrc.setText(Environment.getExternalStorageDirectory()
+ "/2.mp4");
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
private void showToast(String info) {
Toast.makeText(this, info, Toast.LENGTH_SHORT).show();
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_play:
play(0);
break;
case R.id.btn_pause:
pause();
break;
case R.id.btn_replay:
rePlay();
break;
case R.id.btn_stop:
stop();
break;
default:
break;
}
}
/**
* 开启进度条
*/
private void seekBarChanging() {
seekBar_progress.setMax(mediaPlayer.getDuration());
seekBar_progress.setProgress(currentPosition);
timer = new Timer();
timerTask = new TimerTask() {
@Override
public void run() {
if (ischanging == true) {
return;
}
seekBar_progress.setProgress(mediaPlayer.getCurrentPosition());
}
};
timer.schedule(timerTask, 0, 10);
}
/**
* 初始化进度条
*/
private void initSeekBar() {
timer.cancel();
seekBar_progress.setProgress(0);
}
/**
* 播放 正常应写在服务中
*
* @param currentPosition2
*/
private void play(final int Position) {
String path = et_mediaSrc.getText().toString().trim();
File file = new File(path);
if (file.exists()) {
if (mediaPlayer != null) {
mediaPlayer.stop();
// 释放资源
mediaPlayer.release();
mediaPlayer = null;
}
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
// 指定video播放容器
// 播放视频只多一行
mediaPlayer.setDisplay(sv.getHolder());
mediaPlayer.setDataSource(path);
// 异步的准备 不阻塞主线程 但需要注册准备完毕的回调函数
mediaPlayer.prepareAsync();
// 回调
mediaPlayer.setOnPreparedListener(new OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
// 进度条
mediaPlayer.start();
mediaPlayer.seekTo(Position);
seekBarChanging();
}
});
// 播放完毕的回调函数
mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
// 播放完毕后设置播放按钮可用
bt_play.setEnabled(true);
initSeekBar();
}
});
// 播放中出现错误(如流损坏)的回调函数
mediaPlayer.setOnErrorListener(new OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
stop();
return false;
}
});
// 播放开始后设置播放按钮不可用
bt_play.setEnabled(false);
} catch (Exception e) {
showToast("播放失败");
}
} else {
showToast("文件不存在");
}
}
/**
* 停止播放并回收资源
*/
private void stop() {
if (mediaPlayer != null) {
if (mediaPlayer.isPlaying()) {
// 转到开头并关闭对象
mediaPlayer.seekTo(0);
mediaPlayer.stop();
}
// 释放进度条线程
initSeekBar();
// 释放资源
mediaPlayer.release();
mediaPlayer = null;
// 播放完毕后设置播放按钮可用
bt_play.setEnabled(true);
}
}
/**
* 重新播放
*/
private void rePlay() {
if (bt_pause.getText().equals("继续")) {
bt_pause.setText("暂停");
}
if (mediaPlayer != null && mediaPlayer.isPlaying()) {
mediaPlayer.seekTo(0);
} else {
stop();
play(0);
}
}
/**
* 暂停播放
*/
private void pause() {
if (mediaPlayer != null && mediaPlayer.isPlaying()) {
mediaPlayer.pause();
bt_pause.setText("继续");
} else if (bt_pause.getText().equals("继续")) {
mediaPlayer.start();
bt_pause.setText("暂停");
} else {
showToast("当前未播放");
}
}
/**
* 进度条手动处理
*/
private class MySeekListener implements OnSeekBarChangeListener {
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
if (mediaPlayer == null) {
return;
}
if (fromUser) {
// 如果用户拖动才执行 否则造成进度条线程 多重调用
ischanging = true;
mediaPlayer.seekTo(progress);
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
ischanging = true;
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
if (mediaPlayer == null) {
return;
}
mediaPlayer.seekTo(seekBar.getProgress());
ischanging = false;
}
}
}