GSYVideoPlayer 比例适配:setShowType 的 5 种模式怎么选,黑边与变形一次讲清
【免费下载链接】GSYVideoPlayerVideo players (IJKplayer, ExoPlayer, MediaPlayer), HTTPS, 16k page size, danmaku (bullet chat) support, external subtitles, support for filters, watermarks, and GIF screenshots, pre-roll and mid-roll ads, multiple simultaneous playback, basic seeking/dragging, volume and brightness adjustment, play-while-cache support项目地址: https://gitcode.com/GitHub_Trending/gs/GSYVideoPlayer
详情页里一段 16:9 的视频上下黑边被用户截图吐槽,横屏一放大人物又被拉长了。这类视频比例适配问题,在 GSYVideoPlayer 里都归到同一个入口:GSYVideoType.setShowType。本文先讲清这个静态入口的全局副作用,再按业务场景给出选型,最后给一个可以直接搬走的最小切换实现。
一个入口管所有比例:setShowType 全局生效
先看入口。GSYVideoType.setShowType(int type)是静态方法,参数写入类内部的静态字段TYPE,读取用getShowType()。这意味着三件事:
- 全局生效:设置之后,进程内所有播放器实例(包括还没创建的)都按这个比例渲染,不存在"只对某个播放器生效"的说法。
- 不随释放还原:播放器
release()之后TYPE仍保持最后一次设置的值,想恢复默认得再调一次setShowType(GSYVideoType.SCREEN_TYPE_DEFAULT)。 - 默认即原始比例:从不改动的情况下,画面保持视频原始宽高比。
应对方式很直接:把"设置比例"当成播放前的一次显式配置,而不是初始化时写死一次就完事。多页面并存时(列表页加详情页),每个页面在创建播放器前显式设置自己场景需要的比例。如果你用getShowType()做过分支逻辑,也要意识到读到的是全局值,别把它当成当前播放器的私有状态。📌 记住一句话:setShowType改的是全局,不是当前播放器。
另外还有一档没算在 5 种预设里:SCREEN_TYPE_CUSTOM配合setScreenScaleRatio()可以自定义任意比例,自研布局有固定画幅要求时用它。
按场景选模式:列表、详情、全屏、特殊填充
列表流预览,选默认比例。用户刷列表只关心内容完整,小窗口里黑边是可接受的代价,保持原始宽高比即可,它本来就是初始值:GSYVideoType.setShowType(GSYVideoType.SCREEN_TYPE_DEFAULT);。
详情页观影,统一 16:9。现代影视、短视频几乎全是 16:9,详情页强制这个比例,控制栏和进度条的位置在所有视频间就保持一致,用户切换剧集时不会感到控件跳动:GSYVideoType.setShowType(GSYVideoType.SCREEN_TYPE_16_9);。如果源是老电视、纪录片这类 4:3 内容,改用GSYVideoType.setShowType(GSYVideoType.SCREEN_TYPE_4_3);,代价是宽屏设备两侧出现明显黑边。
横屏全屏沉浸,选全屏裁减。体育、演唱会、直播这类内容,观众能接受边缘被裁掉,不能接受黑边。用GSYVideoType.setShowType(GSYVideoType.SCREEN_TYPE_FULL);,注意源码注释提醒:为了让封面显示正常,surface_container的父布局建议用FrameLayout。
监控、广告类特殊填充,才用拉伸全屏。画面变形可接受、又必须铺满的场景(监控墙、特殊广告位)用GSYVideoType.setShowType(GSYVideoType.SCREEN_MATCH_FULL);。正常视频播放别碰它,变形是肉眼可见的。
最小可运行示例:一个按钮循环 5 种比例
下面是能跑起来的最小配置:FrameLayout容器、标准播放器,控制栏里加一个文本按钮。
<FrameLayout android:layout_width="match_parent" android:layout_height="200dp"> <com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer android:id="@+id/detail_player" android:layout_width="match_parent" android:layout_height="match_parent" /> <TextView android:id="@+id/moreScale" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|end" android:text="默认比例" /> </FrameLayout>点击事件按 0→1→2→3→4→0 的顺序循环 5 种模式,每次切换后手动触发渲染层重排,这是 demo 里SampleVideo的做法:
mMoreScale.setOnClickListener(v -> { if (mType == 0) { mType = 1; GSYVideoType.setShowType(GSYVideoType.SCREEN_TYPE_16_9); } else if (mType == 1) { mType = 2; GSYVideoType.setShowType(GSYVideoType.SCREEN_TYPE_4_3); } else if (mType == 2) { mType = 3; GSYVideoType.setShowType(GSYVideoType.SCREEN_TYPE_FULL); } else if (mType == 3) { mType = 4; GSYVideoType.setShowType(GSYVideoType.SCREEN_MATCH_FULL); } else { mType = 0; GSYVideoType.setShowType(GSYVideoType.SCREEN_TYPE_DEFAULT); } changeTextureViewShowType(); mTextureView.requestLayout(); });changeTextureViewShowType()定义在GSYTextureRenderView里,逻辑很简单:比例不是默认值时,把渲染 view 的布局参数从MATCH_PARENT换成WRAP_CONTENT。如果你自定义了渲染层,记得保留这个调用,否则比例切换后画面不会重排。
全屏切换同步比例设置
Android 播放器切全屏时,GSYVideoPlayer 实际会创建一个独立的全屏播放实例。不同步状态的话,用户选了"16:9"再点全屏,画面会弹回默认比例,体验上像是设置丢了。解法:重写startWindowFullscreen,把比例状态复制给新实例并立即应用,退出全屏时在resolveNormalVideoShow里反向同步回来,这是 demoSampleVideo的完整做法:
@Override public GSYBaseVideoPlayer startWindowFullscreen(Context context, boolean actionBar, boolean statusBar) { SampleVideo fullscreen = (SampleVideo) super.startWindowFullscreen(context, actionBar, statusBar); fullscreen.mType = mType; fullscreen.resolveTypeUI(); // 内部调用 setShowType + changeTextureViewShowType return fullscreen; }窗口和全屏各持有一份比例状态,但真正生效的全局值始终只有一个,来回同步的方向别搞反了。
决策速查表
| 模式常量 | 推荐场景 | 主要副作用 |
|---|---|---|
SCREEN_TYPE_DEFAULT | 列表流、需完整画幅的内容 | 容器比例不符时上下或两侧黑边 |
SCREEN_TYPE_16_9 | 详情页、影视播放 | 非 16:9 源被裁剪 |
SCREEN_TYPE_4_3 | 老电视、纪录片等 4:3 源 | 宽屏设备上两侧黑边明显 |
SCREEN_TYPE_FULL | 体育、演唱会等沉浸场景 | 边缘被裁减;父布局建议FrameLayout |
SCREEN_MATCH_FULL | 监控画面、特殊广告位 | 画面拉伸变形 |
继续深入
- gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/utils/GSYVideoType.java:5 种预设常量和
setShowType/getShowType的定义处 - app/src/main/java/com/example/gsyvideoplayer/video/SampleVideo.java:demo 完整实现,含按钮切换与全屏双向同步
- doc/USE.md:官方文档"切换比例"小节,另有
setRenderType等同类全局开关
比例适配本身不复杂,复杂的是把它当全局状态来管理:把setShowType的调用位置固定下来,黑边和变形基本就不会再找上门。想验证更多边界情况,仓库app模块里的 demo 可以逐个打开对照。
【免费下载链接】GSYVideoPlayerVideo players (IJKplayer, ExoPlayer, MediaPlayer), HTTPS, 16k page size, danmaku (bullet chat) support, external subtitles, support for filters, watermarks, and GIF screenshots, pre-roll and mid-roll ads, multiple simultaneous playback, basic seeking/dragging, volume and brightness adjustment, play-while-cache support项目地址: https://gitcode.com/GitHub_Trending/gs/GSYVideoPlayer
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考