效果的展示
旋转前的显示:
image.png
旋转处理后效果:
image.png
如何实现
方法1 .最直接的想法是进行横竖画面的切换。
Activity是横屏显示,视频播放当然也是全屏.细节也无从谈起.
这种做法也有缺点。 在一些第:页,垂直屏幕的切换可能不被允许,或者即使在水平屏幕的切换之后,其它显示元素也可能需要与垂直屏幕的显示元素相同。 现在对这个产品的需求是这样要求的。 那需要别的方法。
方法旋转视图控件。
exoplayer2支持两种类型的显示:表面视图和纹理视图。 表面视图几乎不能旋转。
官方的issue有这个讨论和示例方法:
3359 github.com/Google/ex oplayer/issues/3843
而且,这个方法最后出现的效果,不是我想要的。 轻松旋转view后,效果就是这样的:
image.png
方法自定义MediaCodecVideoRenderer并设置旋转-深度参数
目前,我们的产品使用的exoplayer2版本为2.6.1,相对于最新版本的2.8.3,做法略有不同,但可以用同样的想法实现。
具体而言,扩展默认的MediaCodecVideoRenderer和DefaultRenderersFactory
首先,自定义SogoDefaultRenderersFactory扩展DefaultRenderersFactory,以便可以返回自定义的MediaCodecVideoRenderer类实例
publicclasssogodefaultrenderersfactoryextendsdefaultrenderersfactory {
publicsogodefaultrenderersfactory (上下文) {
super (上下文;
}
publicsogodefaultrenderersfactory (上下文上下文,@ nullabledrmsessionmanagerdrmsessionmanager ) {
super (上下文、drmSessionManager;
}
publicsogodefaultrenderersfactory (上下文上下文,@ nullabledrmsessionmanagerdrmsessionmanager,int extensionRendererMode )
super (上下文、drmSessionManager、扩展渲染模式;
}
publicsogodefaultrenderersfactory (上下文上下文,@ nullabledrmsessionmanagerdrmsessionmanager,int extensionRendererMode,
super (上下文,drmSessionManager,扩展renderermode,allowedVideoJoiningTimeMs;
}
@Override
protectedvoidbuildvideorenderers (上下文上下文,@ nullabledrmsessionmanagerdrmsessionmanager,long allowedvideojoingtimemer videorenderereventlistenereventlistener,int extensionRendererMode,ArrayList out
super.buildvideorenderers (上下文,drmSessionManager,allowedVideoJoiningTimeMs,事件监听器,扩展
for(intI=out.size ) (- 1; i=0; I---- ) {
rendererrenderer=out.get(I;
rendererinstanceofmediacodecvideorenderer (if ) {
out.remove (渲染器;
out.add(I,newsogomediacodecvideorenderer (上下文,MediaCodecSelector.DEFAULT,
allowedVideoJoiningTimeMs,drmSessionManager,false,eventHandler,eventListener,
max _ dropped _ video _ frame _ count _ to _ notify );
}
}
}
}
然后,自定义扩展的MediaCodecVideoRenderer类:相对于由getMediaFormat生成的MediaFormat设置旋转角度。 这里是90度。
ublicclasssogomediacodecvideorendererextendsmediacodecvideorenderer {
publicsogomediacodecvideorenderer (上下文,mediacodecselectormediacodecselector ) {
super (上下文,媒体编码选择器;
}
publicsogomediacodecvideorenderer (上下文,mediacodecselectormediacodecselector,long allowedJoiningTimeMs ) {
super (上下文、媒体解码器选择器、allowedJoiningTimeMs;
}
publicsogomediacodecvideorenderer (上下文上下文,mediacodecselectormediacodecselector,long allowedJoiningTimeMs,@ nullar long allowedjoiningtimems @ nullablevideorenderereventlistenereventlistener,intmaxdroppedframecounttonotify } {
super (上下文、媒体解码器选择器、allowedJoiningTimeMs、eventHandler、eventListener、maxDroppedFrameCountToNotify );
}
publicsogomediacodecvideorenderer (上下文、mediacodecselectormediacodecselector、long allowedJoiningTimeMs、 @nullabledrmsessionmanagerdrmsessionmanager,booleanplayclearsampleswithoutkeys,@Nullable Handler eventHandler,@ nullable
super (上下文、mediaCodecSelector、allowedJoiningTimeMs、drmSessionManager、playClearSamplesWithoutKeys、eventHandler、
}
@Override
protectedmediaformatgetmediaformat (格式,CodecMaxValues codecMaxValues,booleandeviceneedsautofrcworkaround,接口
mediaformatmediaformat=super.getmediaformat (格式,codecMaxValues,deviceNeedsAutoFrcWorkaround,tunnelingaudiosessision
媒体格式. set integer (' rotation-degrees ',90 );
返回介质格式;
}
}
如果垂直视频和水平视频混合使用,如何确定当前视频是水平视频?
通过在exoplayer中设置视频监听器,可以听到视频流的纵横比。 具体接口实现:
公共接口视频监听器{。
voidonvideosizechanged (intwidth,int height,int unappliedRotationDegrees,
浮动像素宽度;
.
}
从width和heigh参数可以看出视频流的宽度较高。
一旦发现它是水平视频流,立即重建exoplayer播放器,并在创建此新播放器时使用上面定义的两个扩展类。
.
var player=exoplayerfactory.newsimpleinstance (sogodefaultrenderersfactory (应用程序),
mTrackSelector )
.
此方法有缺点,仅支持5.0或更高版本。 因为此参数旋转深度仅支持5.0或更高版本
代码示例
马上就来了