Android学习二、MediaPlayer播放视频

MediaPlayer主要是用来播放音频的,因此它没有提供图像输出界面,此时就需要借助于SurfaceView来显示MediaPlayer播放时候的图像输出。

有几点要注意的:

1、MediaPlayer管理播放的,所以状态问题一定不能忽略的。

2、SurfaceHolder.setType(int)方法虽然被标记为deprecate的,但是最好还是对SurfaceView进行这样设置this.surfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

3、最好保证mediaPlayer.start()之后,在进行mediaPlayer.setDisplay()的设置,不过一般问题不大。

4、有时候会遇到只有声音没有图像的情况,那是因为surfaceview的创建优先级并不高,因此在mediaPlayer开始之后,surfaceView还没有创建出来,因此会出现有声音没图像的问题

一般有两种实现方法:

一是在通过holder增加callback,监听surfaceCreate事件,在监听到之后再开始mediaPlayer的相关操作,具体可以看videoView的实现方法

二是通过按钮来实现mediaPlayer,这样也可以保证再用户按到按钮之前,surfaceView已经被创建出来了。



下面是封装的操作播放视频的代码,因为需要,加了一些判断,不过基本的封装都有。

public class OperateMedia implements OnBufferingUpdateListener,
		OnCompletionListener, OnErrorListener {
	private int position = 0;// 保存播放的的位置
	private SurfaceView surfaceView;// surfaceVie对象
	private Context context;// 上下文对象
	private MediaPlayer mediaPlayer;// mediaplayer对象
	private int currentPlay = 0;// 保存当前正在播放的视频 0表示还没有记录
	private boolean justBack = false;// 是否刚才另外一个界面跳回,fasle 表示不是

	public OperateMedia(Context context, MediaPlayer mediaPlayer,
			SurfaceView surfaceView) {
		// TODO Auto-generated constructor stub
		this.context = context;
		this.mediaPlayer = mediaPlayer;
		this.surfaceView = surfaceView;
		// mediaPlayer的设置
		this.mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
		this.mediaPlayer.setOnBufferingUpdateListener(this);
		this.mediaPlayer.setOnCompletionListener(this);
		// surfaceView的设置
		this.surfaceView.getHolder().setKeepScreenOn(true);
		this.surfaceView.getHolder().setType(
				SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
		this.surfaceView.getHolder().addCallback(new SurfaceCallback()); // surfaceView的回调

	}

	// 设置播放不同的视频
	public void loadSrc(int num) {
		// 如果在次播放的是不同的视频,那么就将position初始化,并且reset,重新设置视频源
		if (num != currentPlay) {
			position = 0;
			try {
				currentPlay = num;
				mediaPlayer.reset();
				AssetFileDescriptor fd = null;
				switch (num) {
				case 0:
					fd = context.getAssets().openFd("a.mp4");
					break;
				case 1:
					fd = context.getAssets().openFd("b.mp4");
					break;
				case 2:
					fd = context.getAssets().openFd("c.mp4");
					break;
				case 3:
					fd = context.getAssets().openFd("d.mp4");
					break;
				}
				mediaPlayer.setDataSource(fd.getFileDescriptor(),
						fd.getStartOffset(), fd.getLength());
				play();
			} catch (IllegalArgumentException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IllegalStateException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			return;// 中断当前程序
		}
		// 如果点击的是同一个视频。那么就不用reset了
		if (num == currentPlay) {
			if (justBack) {
				play();
				return;
			} else {//如果不是从另一个activity切换回来,那么,就直接设置到0,开始播放
				mediaPlayer.seekTo(0);
				mediaPlayer.start();
				mediaPlayer.setDisplay(surfaceView.getHolder());// 设置屏幕
			}
		}

	}

	// 播放视频
	public void play() {
		mediaPlayer.prepareAsync();
		mediaPlayer.setOnPreparedListener(new OnPreparedListener() {
			public void onPrepared(MediaPlayer mp) {
				if (position > 0) {
					mediaPlayer.seekTo(position);
					if (justBack) {
						justBack = false;
						position = 0;
					}
				}
				mediaPlayer.start();
			}
		});
		mediaPlayer.setDisplay(surfaceView.getHolder());// 设置屏幕
	}

	// 视频播放完成的回调方法
	public void onCompletion(MediaPlayer mp) throws IllegalStateException {
		if (currentPlay == 0) {
			MediaVideo.justPlay = false;
		}
	}

	//
	public void onBufferingUpdate(MediaPlayer mp, int percent)
			throws IllegalStateException {
	}

	// SurfaceView的callBack
	private class SurfaceCallback implements SurfaceHolder.Callback {
		public void surfaceChanged(SurfaceHolder holder, int format, int width,
				int height) {
		}

		public void surfaceCreated(SurfaceHolder holder) {
			if (position > 0) {
				loadSrc(currentPlay);
			}
		}

		public void surfaceDestroyed(SurfaceHolder holder) {
			// 界面销毁,即将跳转到另外一个界面
			if (mediaPlayer.isPlaying()) {
				justBack = true;
				position = mediaPlayer.getCurrentPosition();
				mediaPlayer.stop();
			}
		}

	}

	public boolean onError(MediaPlayer mp, int what, int extra) {

		return false;
	}

}


推荐一个写的不错的MediaPlayer的文章:点击打开链接

你可能感兴趣的:(android,Class,callback,Constructor)