视频播放器 media player

岳锦
2023-12-01
package cn.itcast.videoplayer;

import java.io.File;

import android.app.Activity;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
// <SurfaceView
  //      android:id="@+id/sv"
 //       android:layout_width="fill_parent"
  //      android:layout_height="fill_parent" />
  //双缓冲,速度高,更流畅.视频播放在单位时间内显示很多帧.涉及到很多图形的生成和渲染,一般的view对象是直接画到屏幕
  //surfaceview 内部 有两个缓冲区a,b.  ab轮流交互填充 第一步 把a填满.  把a显示到界面.同时准备b缓冲区里面的内容.  将b显示. a缓冲区在后台缓冲.
public class DemoActivity extends Activity implements OnClickListener {
	private EditText et_path;
	private Button bt_start, bt_pause, bt_restart, bt_stop;
	private SurfaceView sv;
	private SurfaceHolder holder;
	MediaPlayer mediaPlayer;
	boolean ispause = false;
	int position;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		et_path = (EditText) this.findViewById(R.id.et_path);
		bt_start = (Button) this.findViewById(R.id.bt_start);
		bt_pause = (Button) this.findViewById(R.id.bt_pause);
		bt_restart = (Button) this.findViewById(R.id.bt_restart);
		bt_stop = (Button) this.findViewById(R.id.bt_stop);

		bt_start.setOnClickListener(this);
		bt_pause.setOnClickListener(this);
		bt_restart.setOnClickListener(this);
		bt_stop.setOnClickListener(this);
		sv = (SurfaceView) this.findViewById(R.id.sv);

		// 视频播放的填充器
		holder = sv.getHolder();
		/* 下面设置Surface .不维护自己的缓冲区,而是等待屏幕的渲染引擎将内容推送到用户面前 */
		holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
		// holder.setFixedSize(width, height);

		holder.addCallback(new MyHolderCallback());

	}

	
	
    	
	
	@Override
	protected void onStart() {
		// TODO Auto-generated method stub
		// 后台继续播放 回到 前台 仍然能看到画面 
		super.onStart();
	}




//surfaceCreated   surfaceChanged   surfaceDestroyed
	private class MyHolderCallback implements SurfaceHolder.Callback {

		public void surfaceCreated(SurfaceHolder holder) {
			System.out.println("holder 被创建 ");
			// 当视频播放最小化之后 下一次 必须在holder被创建后 再去播放视频
			if (position > 0) {
				String path = et_path.getText().toString().trim();
				try {
					// 重新设置显示的holder
					DemoActivity.this.holder = holder;
					play(path, position);
				} catch (Exception e) {
					Toast.makeText(getApplicationContext(), "播放出现一次", 0).show();
					e.printStackTrace();
				}
			}

		}

		public void surfaceChanged(SurfaceHolder holder, int format, int width,
				int height) {
			// TODO Auto-generated method stub

		}

		public void surfaceDestroyed(SurfaceHolder holder) {
			System.out.println("holder 被销毁 ");
			// 记录最小化之后播放器播放的位置

			if (mediaPlayer != null && mediaPlayer.isPlaying()) {
			//得到播放的地址,
				position = mediaPlayer.getCurrentPosition();

				mediaPlayer.stop();
				mediaPlayer.release();
				mediaPlayer = null;
			}

		}

	}

	public void onClick(View v) {
		String path = et_path.getText().toString().trim();
		try {
			switch (v.getId()) {
			case R.id.bt_start:

				play(path, 0);
				break;
			case R.id.bt_restart:
				if (mediaPlayer != null && mediaPlayer.isPlaying()) {
					mediaPlayer.seekTo(0);
				} else {
					play(path, 0);
				}
				break;
			case R.id.bt_stop:
				if (mediaPlayer != null && mediaPlayer.isPlaying()) {
					mediaPlayer.stop();
					mediaPlayer.release();
					mediaPlayer = null;
					bt_start.setEnabled(true);
				}
				break;
			case R.id.bt_pause:
				pause();
				break;
			}
		} catch (Exception e) {
			e.printStackTrace();
			Toast.makeText(this, "视频播放失败", 0).show();
		}

	}

	private void pause() {
		if (mediaPlayer != null && mediaPlayer.isPlaying()) {
			mediaPlayer.pause();
			bt_pause.setText("☺");
			ispause = true;
			return;
		}
		if (mediaPlayer != null && ispause) {
			mediaPlayer.start();
			bt_pause.setText("‖");
			ispause = false;
		}
	}

	/**
	 * 根据路径 进行播放
	 * 
	 * @param path
	 */
	private void play(String path, int position) throws Exception {
		if ("".equals(path)) {
			Toast.makeText(this, "路径不能为空", 0).show();
			return;
		}
		File file = new File(path);
		if (file.exists()) {
			mediaPlayer = new MediaPlayer();
			mediaPlayer.setDataSource(path);
			//设置音频流的类型   视频的格式 必须是渐进式的格式
			mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
			//视频在holder里面播放.
			mediaPlayer.setDisplay(holder);
			// 播放视频之前必须要prepare初始化 视频的播放器
			mediaPlayer.prepare();
			mediaPlayer.start();
			mediaPlayer.seekTo(position);
			bt_start.setEnabled(false);
			//
			mediaPlayer.setOnCompletionListener(new OnCompletionListener() {

				public void onCompletion(MediaPlayer mp) {
					// TODO Auto-generated method stub
					mediaPlayer.release();
					mediaPlayer = null;
					bt_start.setEnabled(true);

				}
			});
		

		// 当播放出现错误的时候的回调方法
			mediaPlayer.setOnErrorListener(new OnErrorListener() {

				public boolean onError(MediaPlayer mp, int what, int extra) {
					mp.release();
					mediaPlayer = null;
					bt_start.setEnabled(true);
					return false;
				}
			});

		} else {
			Toast.makeText(this, "文件不存在", 0).show();
			return;
		}

	}
}

 类似资料: