news 2026/10/15 20:50:48

pure_live v2.6.0 阶段稳定版全解析:上游整合、稳定性设计与五平台构建

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
pure_live v2.6.0 阶段稳定版全解析:上游整合、稳定性设计与五平台构建
  • 音视频
  • 直播
  • 移动开发

【免费下载链接】pure_live

纯粹直播:哔哩哔哩/虎牙/斗鱼/快手/抖音/网易cc/YY直播/Twitch直播/SOOP直播/M38自定义源应有尽有。

项目地址:https://gitcode.com/gh_mirrors/pur/pure_live
点击查看免费下载

pure_live 是一款开源的多平台直播聚合播放器,v2.6.0 阶段稳定版(2.6.0+4076)围绕"真实合并上游、修复公开问题、收敛 CPU/GPU/内存热点、全平台串行构建"四条主线完成了一次完整的稳定性迭代。本文基于 v2.6.0 阶段稳定版、近期 Issue 审计、依赖与接口审计 与 构建与发布,结合仓库源码梳理该版本的问题根因、修复实现、依赖策略、质量门禁与五平台产物,帮助读者理解这套"维护分支稳定性优先"的发布方法论。

版本快照与上游基线

项目值
版本号2.6.0+4076
维护仓库liuchuancong/pure_live
上游基线liuchuancong/pure_live@c3ae29bb
发布日期2026-08-23
最终整合源码b1d61b27(门禁)、56275967(五平台最终构建树)

本阶段的核心动作是真实合并上游至c3ae29bb,涉及关注刷新、房间详情补全、版本历史容错、弹幕模板、BetterPlayer 尺寸与 Windows 小窗设置等改动;当上游实现与维护分支的稳定性目标存在语义冲突时,按"维护版稳定性优先"的原则整合,而不是机械照搬。

本阶段范围

1. 上游合并与冲突语义整合

上游c3ae29bb带来的功能面覆盖:

  • 关注刷新:关注页手动/自动刷新链路;
  • 房间详情补全:链接占位房间进入后补齐元数据;
  • 版本历史容错:版本更新历史读取的异常兜底;
  • 弹幕模板:弹幕样式模板体系;
  • BetterPlayer 尺寸与 Windows 小窗设置:播放器尺寸策略与桌面小窗配置。

这些改动在合并时逐一按维护版稳定性目标复评,冲突语义以"不破坏既有用户行为"为底线。

2. 公开 Issue 修复

本轮修复了近期公开问题#765、#769、#770、#771、#773,并吸收#767的高 DPI 性能边界经验,同时覆盖#774(v2.6.0 关注页手动刷新失效)的回归修复。各问题根因与处理详见下文"稳定性设计"。

3. 性能热点收敛

针对首页图片缓存反复驱逐、非 Exo 原生纹理初始化环、画面比例切换重开流三处 CPU/GPU/内存热点做了专项修复,见"稳定性设计"中的对应条目。

4. 依赖更新策略

更新全部可直接升级且与 Flutter 3.47 兼容的依赖;保留有明确类型或原生组合约束的固定项。完整策略见"依赖审计"。

5. 分阶段串行构建

Android、Windows、Linux、macOS、iOS 五平台分阶段串行构建,不向上游提交 PR,产物清单见"串行构建与产物"。

稳定性设计

异步竞态:以"房间号 + 平台 + 加载代次"为提交条件

房间详情、醒目留言(Super Chat)、播放地址与弹幕连接等异步任务,统一以**当前"房间号 + 平台 + 加载代次"(load generation)**为提交条件。迟到响应只结束自身任务,不再覆盖新房间的状态——这是"切房隔离"的基础。

在 直播控制器 及各类弹幕适配器(如 斗鱼弹幕、虎牙弹幕)中都可以看到 generation/epoch 机制的运用,其思路与关注刷新控制器中的_refreshEpoch一脉相承(见下文)。

播放会话复用:PiP、横竖屏、后台恢复

PiP、横竖屏切换、后台恢复继续复用同一播放器和弹幕会话;恢复 revision 只重建展示订阅,只有连接异常时才触发重连。这避免了"转一圈就重开流"的经典问题,也呼应了 #767 修复中"画面适配模式更新只改变布局,不重新拉流"的原则。

有界队列与显式释放

弹幕历史、待处理批次、文本/表情缓存与本地互动队列全部保持有界;直播控制器关闭时统一取消 Worker、Timer、订阅和子控制器。从 关注刷新控制器 的onClose()可以直观看到这一纪律:_refreshEpoch++使所有在途刷新失效,随后依次移除生命周期观察者、取消 Tab 监听、释放全部订阅、取消三类定时器并 dispose 全部 Worker。

图片缓存:按可见尺寸解码、刷新不逐卡驱逐

图片按可见尺寸解码并复用磁盘缓存;刷新只推进全局 epoch,不逐卡删除同一缓存条目。

在 房间卡片封面实现 中:

final cacheWidth = (logicalWidth * MediaQuery.devicePixelRatioOf(context)).round().clamp(240, 720).toInt(); return CachedNetworkImage( imageUrl: coverUrl, cacheKey: epoch == 0 ? coverUrl : '$coverUrl#$epoch', cacheManager: AppImageCacheManager.instance, fit: BoxFit.cover, memCacheWidth: cacheWidth, // 按可见尺寸解码,控制内存占用 useOldImageOnUrlChange: true, // 刷新时保留旧图,避免占位符闪屏 fadeInDuration: Duration.zero, fadeOutDuration: Duration.zero, ... );

关键点在于:cacheKey只随全局 epoch 变化,同一轮刷新不会反复销毁重建每个卡片的图片元素;useOldImageOnUrlChange: true配合memCacheWidth消除了"刷新即闪白/占位符交替"和整网格 CPU 尖峰。面积卡片(area_card.dart)与播放页弹窗(play_other.dart)采用同一模式。

Windows 原生视频视图与画面适配

Windows 原生视频视图受可见视口约束;播放器适配模式更新只改变布局,不重新拉流。这是对 #767(Windows 4K/高 DPI GPU 偏高)的核心修复:此前视频原生视图按源尺寸经FittedBox放大/裁切,窗口变化与呈现更新可能重开数据源;现在非 Exo 输出按可见视口和applyBoxFit约束渲染,画面比例切换仅改呈现 revision。

Windows 小窗:几何独立持久化与多显示器校正

这是 #765 的完整修复,也是本轮 Windows 侧最复杂的稳定性设计:

  • 小窗位置、大小与主窗口几何独立保存;
  • 提供记忆开关(默认开启)与显式重置入口;
  • 默认跟随应用所在显示器;多显示器变化时把旧矩形校正到仍可见的工作区(显示器被移除后回到应用所在屏)。

实现集中在 Windows 小窗驱动:

final DisplayAwarePipWindow windowsPipWindow = DisplayAwarePipWindow( workAreasReader: _readWorkAreas, // 读取全部显示器可见工作区 readSavedBounds: _readSavedBounds, // 仅在开启记忆开关时读取 writeSavedBounds: _writeSavedBounds, // 移动/缩放后写入(横竖屏分桶) alwaysOnTop: () => SettingsService.to.player.windowsPipAlwaysOnTop.value, normalMinSize: const Size(WindowSizeController.minWindowWidth, WindowSizeController.minWindowHeight), );
  • _readWorkAreas()通过screenRetriever.getAllDisplays()枚举各显示器,以visiblePosition/visibleSize构建工作区矩形;无显示器时回退到主显示器;
  • _readSavedBounds()只有在rememberPipPosition为真时才返回记忆的几何,并且横屏/竖屏视频分别持久化(windowsPipShowsPortraitVideo依据驱动内实际视频尺寸判断,避免录像借用直播的朝向记忆);
  • 设置页提供完整的操作面:小窗记忆开关、基准尺寸(200–720 px)、最小宽(100–320 px)、最小高(60–240 px)、自由宽高比、始终置顶与位置重置,其中_syncPipConfig()会把尺寸策略实时推入驱动,_changePipAlwaysOnTop()采用"先应用、失败回滚、再提交状态"的事务式更新。

关注刷新:#774 的根因与修复

Issue #774(v2.6.0 关注页手动刷新失效、未开播仍显示)的根因链条在 近期 Issue 审计 中被拆得很清楚:

  1. 下拉刷新头不可触发:每个平台页虽然重新包了EasyRefresh,但子列表又显式安装了 AndroidClampingScrollPhysics,边界位移先被外层物理模型消耗,刷新头只有回调配置而没有可触发的拖动链路;
  2. 生命周期刷新互相取消:冷启动核验与 450 ms 后的 resumed 刷新通过_refreshEpoch互相取消,失败房间继续沿用上次进程的"开播位";
  3. 网络异常被伪装成成功:部分平台把网络异常伪装成"已下播"结果。

对应修复:

  • 改用EasyRefresh.builder,并把其物理模型直接交给当前平台的唯一纵向列表。在 关注页网格 中有明确注释:EasyRefresh 必须拥有安装在其纵向子列表上的确切 physics,否则 Android 外层ClampingScrollPhysics会先消耗边界位移,导致"回调存在但下拉动画永远无法触发"。
return EasyRefresh.builder( key: ValueKey('favorite_pull_to_refresh_$siteId'), header: MaterialHeader( triggerOffset: 72, triggerWhenRelease: true, clamping: true, ), onRefresh: onRefresh, childBuilder: childBuilder, // physics 由 EasyRefresh 注入唯一列表 );

项目为此还维护了自定义滚动物理模型 pure_live_scroll_physics.dart:iOS/macOS 保留BouncingScrollPhysics原生弹簧,其余平台用ClampingScrollPhysics,导航条/分页视图等有限选择器则用PureLiveBoundedScrollPhysics硬性钳制首尾边界(#769 修复)。

  • 所有刷新经单事务锁串行。在 关注刷新控制器 中,_refreshLock.synchronized保证同一时刻只有一个刷新事务拥有快照写入权:
// One refresh owns the snapshot transaction at a time. The former epoch // scheme cancelled whichever pass happened to finish second; a lifecycle // resume 450 ms after launch could therefore discard startup verification // and leave failed rooms with yesterday's live bit. final pending = _refreshLock.synchronized<void>(() async { final refreshEpoch = _refreshEpoch; ... });

启动/恢复/手动触发绕过失败冷却(bypassFailureCooldown),失败房间进入 5 分钟冷却(_refreshFailureRetryAfter),失败汇总单行输出(summarizeFavoriteRefreshFailures最多列 6 条,避免刷屏)。

  • 启动期间发布"状态未知但位置稳定"的非持久预览:冷启动先按持久化的缓存元数据分桶(在线/录播/离线),但把每个状态位标为 unknown(isVerifyingFavorites),避免陈旧"开播位"误导,也避免 clear/reorder/重现造成的视觉抖动;CC、Twitch、SOOP 使用严格元数据刷新路径,虎牙 REPLAY 进入录播分组。

关注按钮:#773 的响应式修复

Issue #773(链接跳转及普通入口无法关注)的根因是:按钮缓存局部布尔值并依赖 EventBus 刷新;链接占位房间详情补全后身份变化,旧局部状态与持久列表脱节。修复为:按钮直接观察收藏列表并用"平台 + 房间号"复合身份判断,详情未完成时显示加载态,跳转等待导航完成。核心判断在 收藏房间控制器:

bool isFavorite(LiveRoom liveroom) { return favoriteRooms.v.any((candidate) => candidate.hasSameIdentity(liveroom)); }

即关注状态由持久列表实时推导,而不是按钮自己缓存一份可能过期的布尔值。

醒目留言(Super Chat)边界

实时 WebSocket 醒目留言已进入统一消息列表并自动过期;SC 页面直接观察 RxList 实时快照,并按房间代次隔离。在 SuperChatPage 中可以看到它使用独立的primary: false+ClampingScrollPhysics列表,避免继承外层 PrimaryScrollController 导致越界空白(#769 同类问题)。已知边界:斗鱼"进入直播间前已发送且仍有效"的历史醒目留言缺少已验证的稳定公开回补入口,本轮只保证进入后的实时 SC、自动过期与切房隔离。

依赖审计

Dart/Flutter 依赖

  • scrollview_observer 1.27.1为本轮唯一可直接升级项;
  • dynamic_color 1.9.0为当前 Flutter Material API 的兼容线,2.x 主题类型迁移另立任务(后续版本已完成迁移,见 DEPENDENCY_AUDIT.md 中dynamic_color 2.1.0与material_ui桥接)。

Android 工具链

组件版本
AGP9.3.1
Gradle9.5.0
Google Services4.5.0
compileSdk/targetSdk37
字节码目标JDK 17

版本组合遵循 AGP 9.3 官方默认基线;Git、本地路径和 Native Assets 依赖继续锁定完整提交或仓库快照,发布构建使用 lockfile(flutter pub get --enforce-lockfile)。

质量门禁

最终上游整合源码b1d61b27通过本地完整门禁,结果如下:

  • Flutter Analyze:0 issue(耗时 323.8 秒);
  • 单元与 Widget 测试:224/224 通过;
  • 公开接口探测:26/26 通过,覆盖 Bilibili、Douyu、Huya、Kuaishou、Douyin、网易 CC、Twitch 与 SOOP Live;
  • Built-in Kotlin、构建策略、设备 UI 地图、锁文件与变更文件格式检查全部通过;
  • 完整门禁耗时557.633 秒;重型进程峰值内存 5.97 GiB、峰值 CPU 17.27%;结束后活跃重型进程为 0;
  • 记录文件:local-artifacts/build-records/20260822T193705756Z-quality-full.json。

这里的"公开接口探测"对应仓库中的 接口探测脚本,后续版本已扩展为 42 项覆盖更多平台;质量门禁工具链在 BUILD_AND_RELEASE.md 有完整说明(tool/local_ci.ps1 -Scope Full)。

串行构建与产物

各平台严格按Android → Windows → Linux → macOS → iOS串行执行。最终同步上游c3ae29bb后涉及公共播放器代码,因此五个平台均从同一最终代码树56275967重新构建。Android、Linux、macOS 与 iOS 的工作流每轮只启用一个目标平台,Windows 使用本机 Release 构建。此前 iOS 首轮暴露的 Xcode 26 隐式引擎 registrar 可选值错误已由609e8345修复并纳入最终构建。

平台产物SHA-256来源/记录
Android arm64-v8aPureLive-2.6.0-4076-arm64-v8a-release.apk704f7a873905b2d8d89f66b347a128562f6ea0c2ac9f7e9421ef12c4dd230e7756275967;正式 RSA-4096 签名,包名com.mystyle.purelive,仅含arm64-v8a
Windows x64PureLive-2.6.0-windows-x64-setup.exe693a8dba51ca825780309098605c3622724c467e37d23d472847aa35cee3559c56275967;本机 Inno Setup,可选安装目录
Windows x64PureLive-2.6.0-4076-windows-x64-portable.zipb08258dbf747c7aaae5030669d63a1653f60abb251c95de920403db2c51a28b056275967;20260822T195209357Z-build-windowsx64-release.json
Linux x64PureLive-2.6.0-4076-linux-x64.tar.gz4ba6a34c7f7d0d67b244af9d269f4ffe07185953ff4e4f73e57820402bb6b3d556275967
macOS UniversalPureLive-2.6.0-4076-macos-universal.dmg073026d33e50515b8f1ca68fddba609403ba445378924b5a28d2bfd9cfd7380d56275967
macOS UniversalPureLive-2.6.0-4076-macos-universal.zipc6508e80e82b5286a1491b7b0ed09a5cb2d509efe2ed32fc4b40f6358ba1328c同上
iOS arm64PureLive-2.6.0-4076-ios-arm64-unsigned-app.zipe5c888f248da2b3cb9c8f10343494b9e91fcc4246f611fdd862dadbf04349b4556275967
iOS TrollStorePureLive-2.6.0-4076-ios-arm64-trollstore.ipa099756d50f7f82cb01dd5db202f59b56099628bdba6b98960c496d461dd9f564同上;工作流完成临时签名与 IPA 结构验证

Android 使用apksigner复核 v2 签名、版本名和 ABI;全部远端产物侧车校验通过,Linux 归档包含主程序,macOS/iOS 归档包含完整.app结构。

Windows Release 冷启动烟雾测试:372.339 秒、37 个采样点的隔离实例测试,工作集从 307,494,912 B 到 304,701,440 B,私有字节减少 20,561,920 B,CPU 累计仅增加 2.125 秒,未出现随时间持续增长;记录为20260822T195317241Z-windows-release-smoke.json。

已知平台边界

  • 斗鱼历史醒目留言:缺少已验证的稳定公开回补入口;进入直播间后的实时 SC、自动过期与切房隔离已覆盖;
  • iOS:无签名设备归档供自行签名或 TrollStore 使用;播放器默认策略只作用于新配置,尊重已有用户选择(#770 修复即"iOS 新配置默认 IJK,已有显式选择不迁移");
  • 外部直播接口会随平台变化,脚本结果记录的是发布时点状态,并保留失败平台的独立诊断——因此每次发布前都应重新运行 接口探测。

相关文档索引

  • 近期 Issue 审计(2026-08-23):#765/#767/#769/#770/#771/#773/#774 的复现链路、根因与验证映射;
  • 依赖与接口审计:后续版本的依赖升级、媒体栈同步与 16 KB 页面兼容性核验;
  • 构建与发布:本机优先的构建门禁、签名流程与发布检查清单。

从 v2.6.0 的实践可以看出,pure_live 的稳定性方法论是"根因文档化 + 源码级修复 + 有界队列纪律 + 全平台门禁"四步闭环:每一次刷新、每一个异步回调都明确所有权与代次,每一个列表都明确滚动边界,每一张图片都按可见尺寸消费内存。这套做法不仅保证了本次五个平台产物的质量,也为后续版本(依赖审计、16 KB 对齐、媒体栈迁移等)奠定了可复现的发布基线。

  • 音视频
  • 直播
  • 移动开发

【免费下载链接】pure_live

纯粹直播:哔哩哔哩/虎牙/斗鱼/快手/抖音/网易cc/YY直播/Twitch直播/SOOP直播/M38自定义源应有尽有。

项目地址:https://gitcode.com/gh_mirrors/pur/pure_live
点击查看免费下载

相关推荐

上一篇:CLRS 问题 4-2 深度解析:参数传递开销如何改写二分查找与归并排序的渐近复杂度
下一篇:NoSleep防休眠工具:终极Windows防休眠解决方案告别自动锁屏烦恼

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/15 20:50:29

告别npm install慢:pnpm加速依赖安装的原理与迁移指南

前端工程化里有个很有意思的现状&#xff1a;项目越来越大&#xff0c;依赖越来越多&#xff0c;但npm install这个命令反而成了被吐槽最多的一环。一次冷启动安装动辄几百秒&#xff0c;node_modules 体积动辄几个 G&#xff0c;换个分支、跑个 CI 都要重新来一遍。我自己的感…

作者头像 李华
网站建设 2026/10/15 20:45:30

MySQL调优实战:从参数配置到SQL索引优化完整指南

做后端开发这些年&#xff0c;MySQL调优是我见过最容易被神化、也最容易走弯路的领域之一。一说调优&#xff0c;很多人第一反应就是翻出一堆参数&#xff0c;照着网上的“推荐配置”一顿改&#xff0c;结果不但没变快&#xff0c;反而把线上系统搞崩的案例我见过不少。实际上&…

作者头像 李华
网站建设 2026/10/15 20:39:24

Rope-Pearl 视频换脸教程:从装环境到导出成片的完整指南

Rope-Pearl 视频换脸教程&#xff1a;从装环境到导出成片的完整指南 【免费下载链接】Rope GUI-focused roop 项目地址: https://gitcode.com/GitHub_Trending/ro/Rope 想把视频里的人换成另一张脸&#xff0c;又不想写一行代码&#xff1f;Rope-Pearl 是一个带图形界面…

作者头像 李华