Skip to content

Dev - #99

Open
YaChengMu wants to merge 1539 commits into
fish2018:mainfrom
YaChengMu:dev
Open

Dev#99
YaChengMu wants to merge 1539 commits into
fish2018:mainfrom
YaChengMu:dev

Conversation

@YaChengMu

Copy link
Copy Markdown

No description provided.

Silent1566 and others added 30 commits July 25, 2026 23:00
问题:
- 之前的提交只添加了注释,但没有实际移除 PlayerButtonSetting.isVisible() 检查
- 导致全屏/弹幕/投屏图标按钮仍然受播放器按钮设置影响
- 用户关闭设置后,这些按钮消失

修复:
- 进度条旁全屏按钮:移除 !PlayerButtonSetting.isVisible(FULLSCREEN) 检查
- 顶部弹幕图标按钮:移除 !PlayerButtonSetting.isVisible(DANMAKU) 检查
- 顶部投屏图标按钮:移除 PlayerButtonSetting.isVisible(CAST) 检查
- 这些按钮现在只根据自身的功能状态显示(锁定/播放状态/全屏状态)
- 融合模式全屏播放器的中间悬浮按钮(prev/next)、进度条旁全屏、
  顶部弹幕/投屏图标按钮,之前错误地跟随 PlayerButtonSetting
- 现改为只根据集数/锁定/功能可用性显示,与影视原生模式保持一致
- 恢复 inlinePlayerButtonMap 中的 NEXT/PREV:playerActionRow 里的
  文字按钮属于内联动作行(相当于底部控制栏),应继续跟随设置
融合模式全屏播放器的中间悬浮上集/下集按钮,显示阈值从 episodeCount>0
改为 episodeCount>=2,与 VideoActivity(影视原生模式)的 size<2 判断对齐。
单集时两种模式都不显示中间悬浮导航按钮。

setButtonEnabled(可点击状态)保持 episodeCount>0 不变——按钮仅在
>=2 集时可见,单集时的 enabled 状态已无实际影响。
清理:
- 移除 showControl() 中重复设置中间悬浮 prev/next 可见性的三行
  (调试融合模式时误加,真正的融合逻辑在 TmdbDetailActivity,与此无关)
- prev/next 可见性由 setEpisodeAdapter() 统一负责,覆盖所有集数变化场景

新增防回归测试:
- VideoActivityLayoutTest#mobileOverlayButtonsIgnorePlayerButtonSetting
  锁定全屏播放器悬浮/图标按钮(prev/next/fullscreen/cast/danmaku)不含
  PlayerButtonSetting 判断,同时确认底部动作栏仍通过 addActionButton 跟随设置
- TmdbDetailActivityLayoutTest#fusionOverlayButtonsDoNotFollowPlayerButtonSettings
  锁定融合模式全屏 detailControlView overlay 按钮同样不受设置控制
reparseForPlayerSwitch 入口恢复上游 fish2018 的 !spec.isParseSource() 条件。

问题:切核心走 switchPlayerManually -> switchEngine -> reparseForPlayerSwitch,
对直连源异步重新请求 SiteApi.playerContent,重取失败即 onError 导致播放失败;
而退出重进/切集数/切线路走 getPlayer 正常流程,所以能恢复,形成不对称。

该重取分支源于提交 6210658 删除 !spec.isParseSource() 激活了上游本为死代码的
refreshDirectForPlayerSwitch,用于规避 NBY 源一次性防盗链 URL。提交 e7a9b22
移除本地代理旁路机制回归上游后,该规避已无必要,仅剩切核心必失败的副作用。

恢复条件后直连源切核心沿用已有 spec URL 直接 setMediaItem,与上游一致;
canReparse 判断保留,parse 源重新解析不受影响。TV 与手机版共用代码同时生效。
嵌在 NestedScrollView(wrap_content) 中的 RecyclerView,在 TMDB 多阶段异步
apply 期间,若某帧布局定格在'适配器为空'的瞬间,会以 childCount=0 完成布局,
顶层视图清除 FORCE_LAYOUT 认为布局已结束,但 RecyclerView 子树残留了未消费的
脏标志。此后新数据到达时 requestLayout 沿父链上传会因'父已 layoutRequested'
中途短路、到不了 ViewRootImpl,布局遍历再不被调度;同时相同数据被 setItems
去重(changed=false)导致恢复逻辑失效——形成'适配器有数据、屏上 0 卡片'的死锁。

- 新增 rebindAttached:数据同步后直接重绑可见 ViewHolder,覆盖'卡片还在、仅数据变化'
- 新增 recoverRecyclerViewIfDetached:检测错位态后给整条祖先链逐级 forceLayout
  补脏标志、再从顶层发起 requestLayout,绕过短路强制自顶向下重新布局
- 选集区 + 剧照/演员/主创/相关/个性化推荐 7 个列表统一接入恢复逻辑
退出全屏时 surfaceChanged 回调可能不触发(surface对象未变,仅容器View缩小),
导致 bindVideoOutput 快速路径使用全屏时的缓存尺寸通知MPV渲染,造成画面错位/旋转。

修复:快速路径中从 surfaceHolder 重新读取当前尺寸后再应用。

Regression from: 013af11 fix: stabilize mpv surface resize
MPV gpu vo 在快速路径下只更新 android-surface-size 属性,不重新
初始化 EGL 渲染表面,导致退出全屏后画面仍按旧尺寸渲染、错位或旋转。

修复:在快速路径检测到 surface 尺寸变化时强制 detach+reattach,
让 MPV 用新尺寸重建视频输出。

- 新增 attachedSurfaceWidth/Height 缓存已附加尺寸(-1 表示未附加)
- 尺寸变化或读取失败时强制走完整 reattach 流程
- updateSurfaceSize(SurfaceHolder) 返回是否成功读取有效尺寸
- 关键 reattach 日志提升为 Log.i 便于追踪
原实现强制窗口高度为屏幕高度减固定安全区,导致短内容时按钮与文字间留出大片空白,长内容时又超出屏幕裁掉按钮。

改为窗口 WRAP_CONTENT、根布局与滚动区 wrap_content,并在 show() 前用 View.measure() 预测量固定部分高度,基于 android.R.id.content 的可用高度动态计算滚动区 maxHeight,预留 96dp 垂直边距。预测量取代 post() 异步调整以消除高度跳变闪烁。

移除已失效的 AboutDialogLayout 与 getDialogHeight,并更新回归测试。
下载进度文字随数值长度在 1 行(无速度/时间)和 2 行(完整统计)之间变化,导致 progressText wrap_content 高度跳变、弹窗 WRAP_CONTENT 跟着闪烁。

设置 minLines="2" 预留 2 行高度(最长格式正好 2 行),消除内容变化时的高度抖动。
- minLines=2 + maxLines=2 钉死高度为恰好 2 行 @13sp
- 固定字号确保高度恒定(autoSize 会因字号变化导致行高抖动)
- ellipsize=end 兜底:极端情况超长文字截断显示省略号
- 实测最长格式(100% + 高速 + 剩余/已用时间)在典型手机宽度下正好 2 行,不会被截

消除下载过程中进度文字长度变化导致的弹窗高度抖动。
根因:syncVideoSurfaceSize 把原生播放器排除在 setFixedSize 之外,
MPV gpu vo 的 surface buffer 跟随 view 布局,全屏进出时 buffer 尺寸
变化触发 surfaceChanged → EGL viewport/vo 重建 → 黑屏卡顿(EXO 用
固定 buffer 无此问题)。

修复(PlaybackActivity):
- 新增 isMpvGpuFixedSizeSurface():MPV gpu vo 走固定 buffer 的统一
  判据(含视频尺寸已知,消除启动窗口 FIT/FILL 短暂错配),被
  syncVideoSurfaceSize 与 effectiveResizeMode 共用,防条件漂移
- syncVideoSurfaceSize:MPV gpu vo 也走 setFixedSize;与 EXO 不同,
  buffer 总是 fit 到显示 profile(放大也放大),mpv 始终按显示分辨率
  用自带高质量缩放器渲染,SurfaceFlinger 仅 1:1/降采样,画质无损
- effectiveResizeMode:固定 buffer 时不再强制 FILL,改用 FIT 由
  AspectRatioFrameLayout 做黑边(buffer 已是视频比例,FILL 会变形)

兜底(MpvPlayer,「Surface固定尺寸」关闭时生效):
- 缩小才走 vo=null 完整 reattach(放大属性更新即可),fast-path 补
  attachedSurfaceWidth/Height 跟踪,修复先放大后缩小漏检

代价:嵌入态也按显示分辨率渲染,GPU 开销略升;关闭「Surface固定
尺寸」设置可一键回退旧行为。

验证:testLeanbackArm64_v8aDebugUnitTest 361 项通过;
PlayerPlaybackRegressionSourceTest:138 为既存失败(基线 --rerun-tasks
复现,mobile VideoActivity 缺 isVisible 映射,与本次无关)。
同一部剧在不同源、不同线路观看时,历史记录各自独立,「最近观看」会
出现多张重复卡片,切换源或线路后进度还会丢失、从头播放。

改为以 TMDB ID 作为剧集的统一标识:

- History 新增 tmdbId/mediaType/legacyKey 字段(DB 升级至 39),
  播放页 TMDB 匹配完成后直接盖章 tmdbId,不再依赖名称回查缓存。
- 列表按 tmdbId 整剧级折叠,同一部剧只显示一张卡,展示全剧最新进度。
- 续播按 tmdbId 跨源查找最近可续播记录,进入任一源都接着上次看。
- 聚合生效时停用遗留的按名合并:该逻辑会物理删除同名记录,且删除会
  按 tmdbId 级联,导致同剧记录互相覆盖、进度丢失,与聚合所需的多源
  记录保留相冲突。

跨源、跨线路时同一集的 URL 与集名格式往往不同(如「第9集」与
「[277.1MB] 9. xxx」),原有的 URL/集名严格比对会误判为换集并清空
进度。新增 Episode.matchesNumber 按集号兜底,与 Flag.find 的打分找集
逻辑同源,并应用到跨源候选筛选与各处换集判断。

新增「按 TMDB 聚合历史」开关,TV 与手机端设置页均可配置。

已编译验证 leanback/mobile arm64 debug 均通过。
- BaseLoader.clear 改为单线程串行队列(LoaderClearQueue)并返回 Future
- BaseConfig 在取配置锁前先 awaitClear 等待清理完成,等待期间不再持锁
- 各 loader clear 用 SpiderCleanup 包裹,单个 spider 销毁异常不中断整体清理
- clear 增加 reason 来源标签便于日志追踪
- 加固全屏切换的 player 空指针,快照 PlayerManager 避免重复解引用
- 补充 LoaderClearQueue/JarLoader/BaseConfig 生命周期测试
TMDB 各异步数据(推荐/个性化/集数标题)完成时都发送同一个 VOD 事件,
导致 leanback 详情页每次都整页重绑并重放全屏 loading。日志确认手动
切换条目后同一份数据被完整重绑两遍,表现为简介闪回、选集闪烁。

- RefreshEvent 拆出 VOD_CORE / VOD_RECOMMENDATIONS / VOD_PERSONAL /
  VOD_EPISODE_TITLES 四种子类型,vod() 保留并映射到 VOD_CORE 以兼容
  既有调用方;mobile 端四种均走 updateVod 保持原全量刷新语义
- leanback 按类型就地刷新对应区域,仅 VOD_CORE 走整页重绑
- 合并窗口内用 EnumSet 累积待发类型并加锁串行化,避免后台线程与主线程
  并发读写导致丢刷新或并发修改异常
- 手动重新匹配不再盖全屏 loading,改为清空旧展示后就地重绑
- 重置背景幻灯片 signature,并让 TMDB 剧照幻灯片成为背景权威(隐藏
  contextWall),修复背景海报切换条目后不更新
- 分集无 TMDB 剧照时,兜底图改取当前条目自身 backdrop/poster,不再
  停留在进场时固定的海报
- 集数标题补齐时重算卡片模式与 chrome 可见性,修复首次进入卡在纯文本
  态;不走完整 setEpisodeAdapter 以免把列表拽回第一个分段
源列表首行按上键时,焦点精确回到当前选中的分组标签,替代默认的就近几何聚焦,非首行仍逐行上移。
将原精准筛选改为 0-100% 相似度滑轨,默认 30%,并记住用户最后一次选择。
支持真实标题覆盖率、100% 完全匹配和 0% 不过滤,同时完善双端界面、空状态、无障碍描述及单元测试。
- 缓冲滑块/列表范围 1-10 改为 1-15(手机版与电视版)
- MPV 先读秒数换算 buffer*3(上限60s) 改为 buffer*4(上限120s)
- EXO 缓冲插值分母 9 改为 14,适配新范围
- 同步更新持久化 clamp 上限、播放性能对话框显示与循环逻辑
YaChengMu and others added 30 commits August 5, 2026 16:57
修复合并阶段暂停或取消时,分片写入逻辑错误导致合并后的文件永久丢失片段的问题。同时在写入分片前增加状态检查,避免在暂停/取消后继续下载完整分片。另外修复下载剧集列表中选中态与禁用态混淆的问题,将选中态改为使用activated属性,已下载项使用enabled=false禁用,确保列表项状态显示正确。
- 续传时避免清空已下载内容,防止文件空洞导致播放失败
- M3U8下载器改用SpiderDebug统一日志输出
- 优化分片合并逻辑,确保断点续传的正确性
- 跨源历史解析成功后复用普通历史的详情分流

- 直达播放模式继续保留显式续播上下文

- 补充移动端与大屏端回归测试
将 `Path.create(file)` 移至条件块内,确保仅在首次下载(offset==0)或文件不存在时才清空并重建文件,续传时直接以读写模式打开而不截断,避免文件前部出现空洞导致无法播放。
将已匹配条目传入手动搜索弹窗,按 TMDB ID 与媒体类型持续标记当前项。
补充手机与 TV 焦点导航行为,并增加选择定位和界面接线测试。
参考v2版本,改进下载体验:
- 下载通知展示百分比和实时速度
- m3u8分片下载自动计算下载速度
- 修复下载列表进度文字重影问题
- 添加节流机制减少频繁刷新
- 剧集名称过长时启用跑马灯滚动
在清单中注册 DownloadService(前台服务,类型 dataSync)与 DownloadReceiver(非导出),以支持后台下载功能。
跨源聚合进度时保留当前片源的历史线路,并将目标剧集重绑到当前可用线路。

TMDB 异步匹配完成后重新应用历史选择,同时避免覆盖用户在原生增强、沉浸融合等模式中的手动操作。
DownloadListActivity 仅在 mobile 源码集存在,main 不能直接引用,改用类名反射避免编译期依赖,并移除 AndroidManifest 中冗余的声明。
fix(history): 恢复多线路历史选择
fix: 修复点播直播接口名称回填
TV 端在控制按钮持焦时仍按 10 秒空闲超时自动收回,手机端继续保持 5 秒;补充双平台回归测试。
在个性设置中新增首页源锁定开关。
锁定时消费标题左右方向键,避免误切换站源,并在标题旁展示锁定状态。
补充相关回归测试。
避免在 RecyclerView 布局期间刷新线路列表,并补充选集同步与零通知回归测试。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants