doc/RECENT_FEATURES.md
本文档汇总近期 Demo 和基础能力调整,方便回归和二次开发时快速确认入口、API 和注意事项。
| 能力 | Demo 入口 | 主要类 | 说明 |
|---|---|---|---|
| WebVTT 进度条预览 | 打开VIDEO | PreViewGSYVideoPlayer | 通过 WebVTT 缩略图轨道展示预览图,支持独立图片和 sprite 坐标裁剪。 |
| 通用外挂字幕 | 自定义EXO支持字幕、通用字幕非EXO | GSYSubtitleController、GSYSubtitleView | SRT/WebVTT 由播放器 UI 层统一解析和渲染,可跨 IJK、System、Media3 使用。 |
| 完成后保留最后一帧 | 完成保留最后一帧 | KeepLastFrameVideo | Demo 级实现,通过 flag 控制自然播放完成时保留当前渲染画面或回到默认封面态。 |
| 截图语义增强 | 滤镜 Demo、MediaCodec Demo 等 | StandardGSYVideoPlayer、GSYRenderView | 保留视频帧截图,同时新增包含播放器 UI 的组合截图 API。 |
| GLSurfaceView 效果和生命周期 | 滤镜 | DetailFilterActivity、GSYVideoGLView*Render | 整理 GL render 生命周期,补充滤镜、纹理、多窗口、遮罩等 Demo 场景。 |
| 多 URL 清晰度切换稳态优化 | 无缝切换 | SmartPickVideo | 保留双 manager 方案,强化切换过程中的位置同步、超时、失败回退和临时 manager 释放。 |
| Exo 自适应清晰度 | EXO自适应清晰度 | ExoAdaptiveTrackActivity、GSYExo2MediaPlayer | 使用单个 HLS master playlist 或 DASH MPD,由 Media3 TrackSelector 在同一时间线内自适应或固定 video track。 |
| 播放器初始化失败安全处理 | 通用能力 | GSYVideoBaseManager、各 IPlayerManager | 内核创建或初始化失败时走错误回调和资源清理,避免直接 crash。 |
| Exo 缓存生命周期和 GIF 清理 | 通用能力 | ExoSourceManager、GifCreateHelper | 收紧 Exo cache 的打开/释放流程,GIF 生成流程结束或失败时更可靠地清理。 |
按近期提交逐条对应如下:
| 提交 | 文档覆盖 |
|---|---|
Add Exo adaptive quality demo and docs | README*、USE*、RECENT_FEATURES*、UPDATE_VERSION*、ARCHITECTURE.md、GSYVIDEO_PLAYER_PROJECT_INFO* |
Harden smart quality switching | 多 URL 清晰度切换章节、架构层级表、回归清单 |
Harden GL renderer lifecycle and demo | GLSurfaceView 效果章节、架构层级表、回归清单 |
Fix screenshot callbacks and composed capture | 截图能力章节、组合截图 API、架构层级表 |
Add keep last frame demo | 完成后保留最后一帧章节、入口总览、回归清单 |
feat: add unified subtitle support | 通用外挂字幕章节、SUBTITLE_CN.md、入口总览、回归清单 |
Add WebVTT seek preview support | WebVTT 进度条预览章节、入口总览、回归清单 |
Handle player init failures gracefully | 播放器初始化失败安全处理条目、版本说明 |
Improve Exo cache lifecycle and GIF cleanup | Exo 缓存生命周期和 GIF 清理条目、版本说明 |
近期播放能力相关说明已经分散补充到以下文档:
README_CN.md / README.md:首页能力摘要和近期能力入口。doc/USE.md / doc/USE_EN.md:使用层面的 Demo 入口和核心 API。doc/UPDATE_VERSION.md / doc/UPDATE_VERSION_EN.md:Unreleased 版本变更摘要。doc/ARCHITECTURE.md:播放能力在 UI、Manager、Render、Exo manager 等层级上的设计归属。doc/GSYVIDEO_PLAYER_PROJECT_INFO.md / doc/GSYVIDEO_PLAYER_PROJECT_INFO_EN.md:项目结构说明里的近期能力层级映射。doc/SUBTITLE_CN.md:通用字幕专题说明。doc/KEEP_LAST_FRAME.md / doc/KEEP_LAST_FRAME_EN.md:完成后保留最后一帧专题说明。doc/RECENT_FEATURES.md / doc/RECENT_FEATURES_EN.md:近期能力总览、API 和回归清单。构建、依赖、SO、发布、解码器、FAQ 类文档没有强行加入本次播放能力说明,因为它们的主题不是 Demo 功能入口或播放架构。
预览不再依赖客户端对原视频批量抽帧。业务侧可以预生成 WebVTT 缩略图轨道,cue 可以指向独立图片,也可以指向 sprite 坐标:
WEBVTT
00:00:00.000 --> 00:00:05.000
thumbs.jpg#xywh=0,0,160,90
主要 API:
player.setOpenPreView(true);
player.setPreviewVttUrl("https://example.com/thumbs.vtt");
库层提供 GSYVideoPreviewVttParser、GSYVideoPreviewProvider、GSYVideoPreviewFrame,业务层只需要按拖动进度获取对应帧。
外挂字幕能力已从 Media3 专属实现调整为 UI overlay 能力。SRT/WebVTT 由 GSYSubtitleController 加载、解析和根据播放进度刷新,异常时只清空字幕,不影响主视频播放。
基本用法:
GSYSubtitleSource source = new GSYSubtitleSource.Builder("https://example.com/subtitle.srt")
.setMimeType(GSYSubtitleMime.APPLICATION_SUBRIP)
.setLanguage("zh")
.setLabel("中文")
.setDefault(true)
.build();
videoPlayer.setSubtitleSource(source);
videoPlayer.setSubtitleEnabled(true);
详细说明见 SUBTITLE_CN.md。
KeepLastFrameVideo 是 Demo 级实现,核心是覆写自然播放完成后的 UI 状态切换,在不主动释放 render view 的情况下保留画面。详细说明见 KEEP_LAST_FRAME.md。
keepLastFrameVideo.setKeepLastFrameWhenComplete(true);
注意:这是给业务验证交互语义的 Demo,不是全局默认行为。需要根据业务播放器封面、Surface 释放策略、重播逻辑决定是否下沉到基础库。
现有视频帧截图语义保持不变:
player.taskShotPic(listener);
player.saveFrame(file, listener);
新增组合截图语义,用于需要把视频画面和播放器 UI 一起截下来的场景:
player.taskShotPicWithView(listener);
player.saveFrameWithView(file, listener);
当前修复点:
null 或 success=false。GL 相关整理集中在 DetailFilterActivity 和 GSYVideoGLView*Render:
GSYVideoType.GLSURFACE,退出时恢复进入前的 render type。GSYVideoGLViewBaseRender / GSYVideoGLViewSimpleRender 增强 release 和截图回调,降低 GL 生命周期异常导致的卡住风险。滤镜 Demo 可以切换普通滤镜、纹理水印、多窗口播放、图片穿孔、背景高斯等场景。SmartPickVideo 仍然适用于多个独立 URL 的清晰度切换或下一集切换。这个方案不是 HLS/DASH 标准 ABR,核心是使用临时 manager 预加载新 URL,准备好后同步到当前播放位置并提交切换。
当前优化点:
如果服务端可以提供 HLS master playlist 或 DASH MPD,优先使用下面的 Exo 自适应清晰度 Demo。
EXO自适应清晰度 Demo 使用一个 HLS master URL 或一个 DASH MPD URL。Exo/Media3 会把同一个 track group 里的多码率 video track 用于 adaptive playback。
Demo 内置测试源:
https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8https://dash.akamaized.net/envivio/EnvivioDash3/manifest.mpd新增能力:
GSYExoVideoManager.instance().getVideoTrackInfoList();
GSYExoVideoManager.instance().clearVideoTrackOverride();
GSYExoVideoManager.instance().setVideoTrackOverride(groupIndex, trackIndex);
说明:
TrackSelectionOverride 固定到某个 video track。内核初始化相关改动集中在 GSYVideoBaseManager 和各内核 IPlayerManager。当 IJK、System、Exo、AliPlayer 创建或初始化失败时,流程会尽量走 onError 和释放清理,而不是把异常直接抛到业务层导致 crash。
这个能力没有单独 Demo 入口,属于全局稳定性兜底。建议通过非法 URL、缺失解码能力或故意构造异常初始化场景回归,确认播放器进入错误态且应用不崩。
ExoSourceManager 收紧了 Exo cache 的生命周期处理,降低 cache 打开、复用和释放过程中的资源残留风险。GifCreateHelper 在 GIF 生成结束、失败或取消后会更可靠地推进状态和清理临时资源。
这个能力同样没有单独入口。回归时建议覆盖 Exo cache 播放、退出页面、重新进入播放,以及滤镜 Demo 里的 GIF 生成/失败路径。
每次修改这些能力后,至少执行:
./gradlew :gsyVideoPlayer-java:testDebugUnitTest :app:assembleDebug
adb install -r app/build/outputs/apk/debug/app-debug.apk
真机建议检查:
打开VIDEO:拖动进度条,确认 WebVTT 预览图能出现。自定义EXO支持字幕、通用字幕非EXO:本地 SRT、本地 VTT、网络 SRT 都能切换,失败不影响播放。完成保留最后一帧:打开/关闭 flag,确认完成后分别停留最后一帧和回到封面。滤镜:切换滤镜和 GL 场景,确认播放、截图、GIF 不崩。无缝切换:切换多个 URL,确认不回 0,失败可回退。EXO自适应清晰度:HLS 和 DASH 都能播放,轨道列表能显示,自动/固定清晰度能切换。