引子:16年手机小视频功能可以说是井喷式发展,我们公司也有这样的需求,android自带的有VideoView可以实现视频的播放,但是封装的太死,有些业务需求不能满足,所以自己写一个,在这里记下来,权当练手。
我的思路是用MediaPlayer和TextureView来结合实现。(VideoView底层用的也是MediaPlayer,至于为什么不用SurfaceView而用TextureView,是因为SurfaceView不能放在可滑动的控件中,至于具体原因和缺点如果不清楚可自行百度之,TextureView正是为了解决这个问题而存在的
首先我们要继承自TextureView并实现TextureView.SurfaceTextureListener接口,有几个方法是我们必须实现的 :
@Override
public void onSurfaceTextureAvailable(SurfaceTexture arg0, int arg1, int arg2) {
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture arg0) {
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture arg0, int arg1,int arg2) {
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture arg0) {
}
其中我们主要在onSurfaceTextureAvailable方法中初始化mediaplayer,代码如下,我都有详尽的注释:
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
Log.e(TEXTUREVIDEO_TAG,"onsurfacetexture available");
if (mMediaPlayer==null){
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
//当MediaPlayer对象处于Prepared状态的时候,可以调整音频/视频的属性,如音量,播放时是否一直亮屏,循环播放等。
mMediaPlayer.setVolume(1f,1f);
}
});
mMediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
return false;
}
});
mMediaPlayer.setOnBufferingUpdateListener(new MediaPlayer.OnBufferingUpdateListener() {
@Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {
//此方法获取的是缓冲的状态
Log.e(TEXTUREVIDEO_TAG,"缓冲中:"+percent);
}
});
//播放完成的监听
mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
mState = VideoState.init;
if (listener!=null) listener.onPlayingFinish();
}
});
}
//拿到要展示的图形界面
Surface mediaSurface = new Surface(surface);
//把surface设置给MediaPlayer
mMediaPlayer.setSurface(mediaSurface);
mState = VideoState.palying;
}
在onSurfaceTextureDestroyed方法中,停止mediaplayer:
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
mMediaPlayer.pause();
mMediaPlayer.stop();
mMediaPlayer.reset();
if (listener!=null)listener.onTextureDestory();
return false;
}
做到这一步我们基本上就可以简单的播放视频了,调用以下代码进行播放:
mMediaPlayer.reset();
mMediaPlayer.setDataSource(url);
mMediaPlayer.prepare();
mMediaPlayer.start();
解决播放时候视图拉伸的问题:
但是在播放的时候我发现视频是拉伸的,就像这样:
相当于ImageView的FIT_XY的形式,导致整个看起来拉伸变形,而我们的要求是铺满但不变形拉伸,就相当于ImageView的CenterCrop形式,所以还应该对