效果展示

旋转前的显示:

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之后支持

代码示例

马上就来

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

  1. 原生js实现点击按钮切换全屏!

    使用fullScreen API实现全屏 <head><meta charset="UTF-8"><meta name="viewport& ...

  2. MediaPlayer+TextureView,完美切换全屏、小窗口的 Android 视频播放器

    NiceVieoPlayer 项目地址:xiaoyanger0825/NiceVieoPlayer  简介:MediaPlayer+TextureView,完美切换全屏.小窗口的 Android 视频 ...

  3. 2022.05.20-电脑切换全屏与非全屏(特别是谷歌浏览器)的时候会发生卡顿黑屏

    切换全屏与非全屏的时候会发生卡顿黑屏 可能是自己之前插的两块屏幕,后来一块屏幕断掉了,再将那一块屏幕接上去就好了 这个很有可能是谷歌浏览器造成的,因为往往是谷歌浏览器切屏的时候才会出现这个问题,而其他 ...

  4. Android 切换全屏,取消全屏

    切换全屏,取消全屏 /*** 切换全屏,取消全屏** @param isChecked*/ private void switchFullScreen(boolean isChecked) {if ( ...

  5. python怎么退出全屏_在notepad++中怎么退出全屏模式

    Notepad++ 它运行便携,体积小.资源占用小,支持众多程序语言,比如C++.C#.Java 等主流程序语言:支持HTML.XML.ASP,Perl.Python.JavaScript 等网页/脚 ...

  6. Flash全屏播放外部多个Flv视频并且按键进行切换+全屏播放外部Flv视频+指定元件播放外部Flv视频(非全屏)(可以作为遮罩来播放)

    目录 一.目的: 1.Flash全屏播放外部多个Flv视频并且按键进行切换+全屏播放外部Flv视频+指定元件播放外部Flv视频(非全屏),所以将其记录下来 二.参考: 1.[AS3编程教学]如何加载并 ...

  7. win10玩cf不能全屏_游戏莫名卡顿四招搞定!Win10游戏优化教程

    很多网友都说Win10下玩游戏卡顿,相反在Win7里就会好很多.这一方面是由你的电脑硬件决定,另一方面也和游戏版本有关.通常来说,新游戏对于Win10的兼容性会更好一些.此外在Win10里,也有一些简 ...

  8. 设置网页打开默认全屏_微信公众号里的视频不能进行全屏播放的解决方法

    我们手机版的微信视频,发现视频播放只能竖屏播放,点击右下角对放大按钮也是如此,网页版也是小窗口播放,而视频这样显示特别影响我们的观看感受, 下面说下微信公众号里的视频不能进行全屏播放的解决方法. 1. ...

  9. win10玩cf不能全屏_游戏莫名卡顿三招搞定!Win10游戏优化教程

    [PConline 技巧]很多网友都说Win10下玩游戏卡顿,相反在Win7里就会好很多.这一方面是由你的电脑硬件决定,另一方面也和游戏版本有关.通常来说,新游戏对于Win10的兼容性会更好一些.此外 ...

  10. jquery video全屏_用videojs让HTML5视频在移动端全屏的方法

    用videojs让HTML5视频在移动端全屏的方法 文章标签: 视频 : 04-10 19:23 : 1859次 : 0条 1赞 点赞 简介在使用videojs插件时,如何让HTML5的视频在移动端里 ...

最新文章

  1. [QA]Python字节码优化问题
  2. 常见虚拟主机目录对照及星外提权目录
  3. 华为交换机同步linux时间服务器,华为s5720s系列交换机同步时间
  4. swift5导航栏标题文字属性设置
  5. highCharts使用中问题总结
  6. Keras 训练时出现 CUDA_ERROR_OUT_OF_MEMORY 错误
  7. 马斯克:挑战纽北赛道的Model S配有7个座椅
  8. modelsim仿真ROM IP数据输出为0的解决办法
  9. 【转】郭敬明作品中100句经典的话
  10. 理解Java虚拟机体系结构
  11. 【REDIS】redis安装
  12. yigo基础学习笔记3_数据映射_上引下推
  13. JavaEE经典试题(一)
  14. Linux源码安装apache
  15. C语言--指针一般在什么时候需要申请内存空间
  16. 802.11a/b/g/n/ac, 802.11kvr 说明
  17. ESXI 虚拟交换机配置 Trunk 端口组
  18. AntDesign表格中下拉菜单
  19. 牛客小白月赛5 A 无关(relationship)
  20. 信息系统规划工具中的各种矩阵

热门文章

  1. 源码分享—《Java多线程编程核心技术》源码,Java多线程编程核心技术源码 略微有改动。
  2. oracle delete误删除表数据进行恢复
  3. 车载前视摄像头学习笔记 ———— 摄像头输出数据格式(RGB)
  4. 《管理的实践》读书心得摘录
  5. 一次量产恢复U盘真实容量的操作过程(安国主控芯片)
  6. 如何从 Hibernate官网下载 hibernate原码 和hibernatetools
  7. 几种将网站设为首页的代码
  8. 广告终结者:使用AdBlock Plus屏蔽百度、CSDN广告
  9. 《SVN web管理工具CollabNetSubversionEdge》
  10. MIPS中lw指令运行时间最长