exoplay切换全屏_如何使用rotation-degrees手动旋转(rotate)exoplayer2播放器

效果展示

旋转前的显示:

image.png

旋转处理后的效果:

image.png

如何实现

方法一. 最直接的想法是进行横竖屏切换.

Activity变成横屏显示了, 视频播放自然也就全屏了. 没什么可细说的.

这个做法也有缺点: 有些情况下某些页面不允许进行横竖屏切换, 或者横竖屏切换后, 仍然要保持其他显示元素与竖屏时一样. 我们现在这个产品的需求就是这么要求的. 那就需要另想办法了.

方法二. 旋转view控件.

对于exoplayer2 来说支持surface view 和texture view两种显示. surface view基本就没办法旋转了.

官方的issue里有这方面的讨论, 及示例做法:

https://github.com/google/ExoPlayer/issues/3843

然后这个办法最后呈现出来的效果, 却不是我想要的. 简单的旋转view之后, 效果是这样的:

image.png

方法三. 定制MediaCodecVideoRenderer, 设置rotation-degrees参数

目前我们产品用的exoplayer2的版本是2.6.1 对于最新版本的2.8.3, 做法稍有不同, 但是同样的思路都能实现.

具体来说就是扩展默认的MediaCodecVideoRenderer和DefaultRenderersFactory

先是自定义SogoDefaultRenderersFactory 扩展DefaultRenderersFactory , 从而能够返回我们自定义的MediaCodecVideoRenderer类实例

public class SogoDefaultRenderersFactory extends DefaultRenderersFactory {

public SogoDefaultRenderersFactory(Context context) {

super(context);

}

public SogoDefaultRenderersFactory(Context context, @Nullable DrmSessionManager drmSessionManager) {

super(context, drmSessionManager);

}

public SogoDefaultRenderersFactory(Context context, @Nullable DrmSessionManager drmSessionManager, int extensionRendererMode) {

super(context, drmSessionManager, extensionRendererMode);

}

public SogoDefaultRenderersFactory(Context context, @Nullable DrmSessionManager drmSessionManager, int extensionRendererMode, long allowedVideoJoiningTimeMs) {

super(context, drmSessionManager, extensionRendererMode, allowedVideoJoiningTimeMs);

}

@Override

protected void buildVideoRenderers(Context context, @Nullable DrmSessionManager drmSessionManager, long allowedVideoJoiningTimeMs, Handler eventHandler, VideoRendererEventListener eventListener, int extensionRendererMode, ArrayList out) {

super.buildVideoRenderers(context, drmSessionManager, allowedVideoJoiningTimeMs, eventHandler, eventListener, extensionRendererMode, out);

for (int i = out.size() - 1; i >= 0; i--) {

Renderer renderer = out.get(i);

if (renderer instanceof MediaCodecVideoRenderer) {

out.remove(renderer);

out.add(i, new SogoMediaCodecVideoRenderer(context, MediaCodecSelector.DEFAULT,

allowedVideoJoiningTimeMs, drmSessionManager, false, eventHandler, eventListener,

MAX_DROPPED_VIDEO_FRAME_COUNT_TO_NOTIFY));

}

}

}

}

下面是自定义扩展MediaCodecVideoRenderer类: 在getMediaFormat中对生成的MediaFormat 设置旋转角度. 这里是90度.

ublic class SogoMediaCodecVideoRenderer extends MediaCodecVideoRenderer {

public SogoMediaCodecVideoRenderer(Context context, MediaCodecSelector mediaCodecSelector) {

super(context, mediaCodecSelector);

}

public SogoMediaCodecVideoRenderer(Context context, MediaCodecSelector mediaCodecSelector, long allowedJoiningTimeMs) {

super(context, mediaCodecSelector, allowedJoiningTimeMs);

}

public SogoMediaCodecVideoRenderer(Context context, MediaCodecSelector mediaCodecSelector, long allowedJoiningTimeMs, @Nullable Handler eventHandler, @Nullable VideoRendererEventListener eventListener, int maxDroppedFrameCountToNotify) {

super(context, mediaCodecSelector, allowedJoiningTimeMs, eventHandler, eventListener, maxDroppedFrameCountToNotify);

}

public SogoMediaCodecVideoRenderer(Context context, MediaCodecSelector mediaCodecSelector, long allowedJoiningTimeMs, @Nullable DrmSessionManager drmSessionManager, boolean playClearSamplesWithoutKeys, @Nullable Handler eventHandler, @Nullable VideoRendererEventListener eventListener, int maxDroppedFramesToNotify) {

super(context, mediaCodecSelector, allowedJoiningTimeMs, drmSessionManager, playClearSamplesWithoutKeys, eventHandler, eventListener, maxDroppedFramesToNotify);

}

@Override

protected MediaFormat getMediaFormat(Format format, CodecMaxValues codecMaxValues, boolean deviceNeedsAutoFrcWorkaround, int tunnelingAudioSessionId) {

MediaFormat mediaFormat = super.getMediaFormat(format, codecMaxValues, deviceNeedsAutoFrcWorkaround, tunnelingAudioSessionId);

mediaFormat.setInteger("rotation-degrees", 90);

return mediaFormat;

}

}

对于竖屏比例视频和横屏比例视频混杂的情况下, 怎么才能判断当前是横屏视频呢?

-- 可以通过为exoplayer设置VideoListener, 来监听视频流的宽高比. 具体接口实现:

public interface VideoListener {

.............

void onVideoSizeChanged(int width, int height, int unappliedRotationDegrees,

float pixelWidthHeightRatio);

....

}

通过width和heigh参数可知视频流的宽高.

当发现是横屏视频流之后, 我的做法是马上重建了一个exoplayer播放器, 并在创建这个新的播放器时,使用上面定义的两个扩展类.

.....

var player = ExoPlayerFactory.newSimpleInstance(SogoDefaultRenderersFactory(application),

mTrackSelector)

....

这个方法有个缺点, 只支持5.0之后的版本, 因为这个参数rotation-degrees只在5.0之后支持

代码示例

马上就来

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值