您的位置:首页 > 移动开发 > Android开发

Android MediaPlayer播放视频

2015-07-22 10:56 477 查看
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已经被创建出来了。

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

[java] view plaincopy

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的文章:点击打开链接
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: