MediaPlayer+TextureView全屏播放视频
2017-09-21 19:07
2306 查看
项目需要做一个简单的播放视频功能demo,考虑到需求较简单(实现不超过2min的MP4格式短视频播放),所以就没考虑使用复杂的第三方视频库了。最初敲定使用系统原生的VideoView实现,后来发现不能在列表中使用普通的VideoView
。VideoView 继承自SurfaceView,而SurfaceView并没有UI同步缓冲区。这就导致了在列表滚动的时候,正在播放的视频可能无法跟上滚动的步伐。针对这个问题继续查资料,最终选择使用MediaPlayer+TextureView实现视频播放。相关的资料很多,这里就不细说了。我主要说一下实现全屏播放的实现思路及遇到的问题。
一、在activity中留一个全屏的ViewGroup放置播放器实现全屏
在相应Activity中预留一个放置播放器的宽高都是match_parent的ViewGroup,大小切换就是把播放器添加到本来的小容器和添加到全屏的ViewGroup中来回切换。
全屏时,把从当前视图移除的播放器View即自定义的TextureView重新添加到预留的ViewGroup中,并且设置activity为横屏。
在activity中监听屏幕状态变化:
相应的实现点击全屏按钮实现全屏逻辑:
退出全屏倒着做就好了,设置会竖屏,将
注意:切换横竖屏时为了避免
到了这里别以为已经万事大吉了,亲自实践发现小屏播放和切换大屏衔接的不好,会出现短暂的黑屏现象。这是因为切换到大屏
时视频view从当前播放视图移除重新添加到大屏视图后,TextureView会重绘,就会重新new一个surfaceTexture,并重新回调onSurfaceTextureAvailable()
方法,这样TextureView的数据通道SurfaceTexture发生了变化,但是mediaPlayer还是持有原来的SurfaceTexture。
解决方法:重写onSurfaceTextureAvailable()、onSurfaceTextureDestroyed(),在从当前视图移除播放器viwe之前保存当前SurfaceTexture,
重新添加到大屏视图时,将之前保存的SurfaceTexture重新设置给当前播放器view。
参考:
VideoView and TextureVideoView on Android
Android视频播放器实现小窗口和全屏状态切换
[Android基础] VideoView
。VideoView 继承自SurfaceView,而SurfaceView并没有UI同步缓冲区。这就导致了在列表滚动的时候,正在播放的视频可能无法跟上滚动的步伐。针对这个问题继续查资料,最终选择使用MediaPlayer+TextureView实现视频播放。相关的资料很多,这里就不细说了。我主要说一下实现全屏播放的实现思路及遇到的问题。
一、在activity中留一个全屏的ViewGroup放置播放器实现全屏
在相应Activity中预留一个放置播放器的宽高都是match_parent的ViewGroup,大小切换就是把播放器添加到本来的小容器和添加到全屏的ViewGroup中来回切换。
全屏时,把从当前视图移除的播放器View即自定义的TextureView重新添加到预留的ViewGroup中,并且设置activity为横屏。
在activity中监听屏幕状态变化:
@Override public void onConfigurationChanged(Configuration newConfig) { TestLog.d(TAG, "onConfigurationChanged : fullScreen=" + fullScreen); super.onConfigurationChanged(newConfig); if (fullScreen != null && newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE && getVideoContent() != null) { getVideoContent().setClickable(true);//拦截点击事件 ViewUtils.setVisible(getVideoContent(), View.VISIBLE); fullScreen.full(); fullScreen = null; } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) { ViewUtils.setVisible(getVideoContent(), View.GONE); } }
相应的实现点击全屏按钮实现全屏逻辑:
public void clickESC() { PingbackUtils_3_9_0.pingVideoFullScreen(); if (mAdapter != null) { final Context context = mAdapter.getContext(); if (context instanceof BaseActivity) { ((BaseActivity) context).setFullScreen(new IFullScreen() { @Override public void full() { handler.addVideo((ViewGroup) ((BaseActivity) context).getRootView(), false); TestLog.d(TAG, TestLog.isDebug() ? "clickESC videoInfo.getCurrentPosition()=" + videoInfo.getCurrentPosition() : ""); //handler.seekTo(videoInfo.getCurrentPosition()); handler.fullScreen((BaseActivity) context);//这个要放到addVideo后面,需要是否全屏的状态 } }); SingleVideoHandler.setOrientation((BaseActivity) context); } } }
退出全屏倒着做就好了,设置会竖屏,将
播放器view从
ViewGroup中移除,重新添加到当前视图。
注意:切换横竖屏时为了避免
Activity重新走生命周期,需要在
Manifest.xml的
activity标签下添加如下配置:
android:configChanges="orientation|keyboardHidden|screenSize"
到了这里别以为已经万事大吉了,亲自实践发现小屏播放和切换大屏衔接的不好,会出现短暂的黑屏现象。这是因为切换到大屏
时视频view从当前播放视图移除重新添加到大屏视图后,TextureView会重绘,就会重新new一个surfaceTexture,并重新回调onSurfaceTextureAvailable()
方法,这样TextureView的数据通道SurfaceTexture发生了变化,但是mediaPlayer还是持有原来的SurfaceTexture。
解决方法:重写onSurfaceTextureAvailable()、onSurfaceTextureDestroyed(),在从当前视图移除播放器viwe之前保存当前SurfaceTexture,
重新添加到大屏视图时,将之前保存的SurfaceTexture重新设置给当前播放器view。
@Override public void onSurfaceTextureAvailable(final SurfaceTexture surface, final int width, final int height) { TestLog.d(TAG, TestLog.isDebug() ? "onSurfaceTextureAvailable:surface=" + surface : ""); TestLog.d(TAG, TestLog.isDebug() ? "onSurfaceTextureAvailable:mSurfaceTexture=" + mSurfaceTexture : ""); if (Utils.hasJellyBeanMR2()) {//如下方法在android4.2会崩溃,所以4.3之后(包括4.3)再使用 if (mSurfaceTexture == null) { mSurfaceTexture = surface; TestLog.d(TAG, TestLog.isDebug() ? "after set:mSurfaceTexture=" + mSurfaceTexture : ""); openVideo(); } else { setSurfaceTexture(mSurfaceTexture); } } else { mSurface = new Surface(surface); openVideo(); } } @Override public boolean onSurfaceTextureDestroyed(final SurfaceTexture surface) { TestLog.d(TAG, TestLog.isDebug() ? "onSurfaceTextureDestroyed:surface=" + surface : ""); // after we return from this we can't use the surface any more /*if (mSurface != null) { mSurface.release(); mSurface = null; } if (mMediaController != null) mMediaController.hide(); release(true); return true;*/ return mSurfaceTexture == null; }
参考:
VideoView and TextureVideoView on Android
Android视频播放器实现小窗口和全屏状态切换
[Android基础] VideoView
相关文章推荐
- MediaPlayer+TextureView全屏播放视频
- mediaplayer+surfaceview实现视频播放以及全屏窗口切换
- TextureView+MediaPlayer实现在线短视频播放
- TextureView+MediaPlayer播放本地视频
- MediaPlayer+TextureView实现小视频居中(不拉伸)播放
- Android MediaPlayer+SurfaceView播放视频(附Demo)
- surfaceview+mediaplayerview实现本地网络视频播放
- videoview循环播放网络视频 和mediaplayer+sufaceview播放网络视频
- android开发SurfaceView+MediaPlayer实现视频播放
- SurfaceView+MediaPlayer 播放视频 锁屏 没有画面等各种问题的解决方案。
- Android SurfaceView+MediaPlayer实现视频播放
- Android SurfaceView + MediaPlayer实现分段视频无缝播放
- android 随手记 videoview循环播放网络视频 和mediaplayer+sufaceview播放网络视频
- android视频播放(二) 利用android原生的MediaPlayer+SurfaceView
- SurfaceView+MediaPlayer实现视频播放
- Android - SurfaceView + MediaPlayer实现分段视频无缝播放
- 用MediaPlayer+TextureView封装一个完美实现全屏、小窗口的视频播放器
- SurfaceView+MediaPlayer视频播放并用SharedPreferences实现暂停功能
- Android MediaPlayer+SurfaceView播放视频 (异常处理)
- 使用mediaplayer + surfaceview来播放视频