TextureView SurfaceView和MediaPlayer的視訊播放
阿新 • • 發佈:2019-01-24
首先看一下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關聯即可.