首先看一下SurfaceView和MediaPlayer的使用,直接上代码
holder = surfaceView.getHolder();//拿到surfaceView的holder
holder.addCallback(new Callback() {//设置监听
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
if (mMediaPlayer != null && mMediaPlayer.isPlaying()) {
mMediaPlayer.stop();
mMediapPlayer.release();
mMediaPlayer = null;
}
}
//SurfaceView创建的监听
@Override
public void surfaceCreated(SurfaceHolder holder) {
//这里可以给视频设置加载背景,避免视频加载时出现黑屏
relativeLayout.setVisibility(View.GONE);
surfaceView.setBackgroundResource(R.drawable.loading);
//初始化播放器
initMediaPlayer();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
}
});
//初始化播放器
private void initMediaPlayer() {
if (null == mMediaPlayer) {
mMediaPlayer = new MediaPlayer();
}
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
//mMediaPlayer.setDisplay(holder);
mMediaPlayer.setOnCompletionListener(new OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
LogUtils.d(TAG, "播放完成");
mMediaPlayer.seekTo(0);
pause();
}
});
mMediaPlayer.reset();
LogUtils.d(TAG, "第一次播放设置路径path::::::1" + path);
mMediaPlayer.setDataSource(path);
mMediaPlayer.prepareAsync();
mMediaPlayer.setOnPreparedListener(new OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
LogUtils.d(TAG, "准备完成");
//准备完成后才给视频播放设置holder
mMediaPlayer.setDisplay(holder);
mMediaPlayer.start();
mMediaPlayer.seekTo(0);
mMediaPlayer
.setOnSeekCompleteListener(new OnSeekCompleteListener() {
@Override
public void onSeekComplete(MediaPlayer mp) {
mMediaPlayer.pause();
//当视频seekTo到0 秒时,去掉加载的背景图片,显示暂停在0秒的视频,避免黑屏
surfaceView.setBackgroundResource(0);
relativeLayout.setVisibility(View.VISIBLE);
LogUtils.d(TAG, "path::::::2" + path);
}
});
LogUtils.d(TAG, "准备完成");
}
});
}
SurfaceView和MediaPlayer使用要比Android自带的VideoView使用起来扩展性更强,可以显示视频加载的图片,VideoView由于内部封装好了SurfaceView和MediaPlayer,但是又很少对外暴漏接口,使用起来不方便.
但是SurfaceView和MediaPlayer使用时也会有缺陷:
1.不能随意更改视频的显示大小,也不能旋转屏幕
2.当在ListView中放置SurfaView+MediaPlayer之后,滑动是,SurfaceView会出现严重的抖动,即视频的上下区域会出现很明显的黑屏,很不协调.
所以后面考虑了TextureView+MediaPlayer,由于TextureView本身就是一个View,故其功能更强大,也可以避免SurfaceView抖动的黑屏问题,先上代码,具体见代码注释.
textureView.setAlpha(0.5f);//设置透明度
textureView.setRotation(45);//设置旋转
textureView.setMinimumWidth(300);//设置宽度
textureView.setSurfaceTextureListener(this);
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture,
int width, int height) {
LogUtils.d(TAG, "onSurfaceTextureAvailable:width:height--:" + width
+ "--:" + height);
mSurface = new Surface(surfaceTexture);
//在这里初始化MediaPlayer ,和上面的一样,
initMediaPlayer();
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width,
int height) {
LogUtils.d(TAG, "onSurfaceTextureSizeChanged");
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
LogUtils.d(TAG, "onSurfaceTextureDestroyed");
if (null != mMediaPlayer) {
mMediaPlayer.reset();
}
return false;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
LogUtils.d(TAG, "onSurfaceTextureUpdated");
}
但是TextureView本身多了很多API,还可以设置宽高比等等,并且在ListView中展示时候也不会出现抖动黑屏,复用的时候,我们只需要重新设置播放器并将其与TextView的Surface关联即可.