首页 / 资讯中心 / 文章详情

pure_live 工具箱直播链接解析审计与实现解析:从“首链接正则“到 HTTP(S) URI 主机路径契约

pure_live 工具箱直播链接解析审计与实现解析:从“首链接正则“到 HTTP(S) URI 主机路径契约 ★ FEATURED ARTICLE
音视频直播移动开发【免费下载链接】pure_live纯粹直播:哔哩哔哩/虎牙/斗鱼/快手/抖音/网易cc/YY直播/Twitch直播/SOOP直播/M38自定义源应有尽有。项目地址https://gitcode.com/gh_mirrors/pur/pure_live点击查看免费下载导读本文围绕 pure_live 开源项目在 2026-09-07 完成的工具箱直播链接解析专项审计展开ToolBoxController.jumpToRoom跳转房间与直链获取共用LiveUrlTool.parseLiveUrl旧实现长期依赖取分享文本第一个 URL 整串 contains 判断平台 逐平台正则提取 ID导致大写协议、相似域名、查询参数、伪装后缀等大量误判。本文完整梳理该批审计发现的问题清单、修订后的 URI/主机/路径契约、94/94 定向回归门禁与最终源码结果并结合仓库当前实现给出可复现的解析规则与边界说明帮助读者理解 pure_live 如何把剪贴板/手动输入的直播分享文本稳健地解析为平台 房间 ID。一、审计背景剪贴板识别与手动解析共享同一契约本批审计基线为提交96c5ad55是 工具箱剪贴板与页面入口审查2026-09-07 的延续。上一轮解决了剪贴板自动填充的生命周期问题本批则进一步区分两类解析场景本地身份解析从分享文本中直接提取平台 房间 ID不发起任何网络请求远端短链/直播接口解析对b23.tv、v.douyin.com等短链做重定向跟随或调用直播信息接口换取身份。两个场景共用同一个入口LiveUrlTool.parseLiveUrl见 live_url_tool.dart而ToolBoxController的跳转房间与获取直链两个动作在 toolbox_controller.dart 的_resolve中统一走parseLink?.call(text) ?? LiveUrlTool.parseLiveUrl(...)。注意审计中提到的LiveUrlTool.getLivePlayUrl是当时调用链的入口表述当前仓库实现中解析契约统一收敛在LiveUrlTool.parseLiveUrl工具箱通过注入的parseLink或默认实现调用它。审计同时与冻结上游c6c9bd70aedc503c003110dae10a83ad0bb891d8做了只读比较上游存在相同的首链接/contains/正则逻辑因此本批问题被归类为upstream-existing上游既有问题并非远端最新版结论。二、首个错误状态与来源旧实现的四大结构性缺陷审计文档明确指出错误在发起直播请求之前就已经产生。旧实现parseLiveUrl修订前版本的核心逻辑为取分享文本中的第一个 URL作为唯一候选用整串文本做contains判断平台而不是解析后的主机名逐平台正则提取房间 ID对快手/CC 使用包含查询参数的整串末尾锚点对抖音www空路径直接调用pathSegments.last。从源码结构看这些做法在四个层面埋下错误层面旧行为典型后果URL 提取只看第一个正则命中首个无关链接会遮蔽后面的 AcFun 房间平台判定整串contains不看主机相似域名、未知主机查询中嵌入的虎牙地址、userinfo 被误判ID 提取逐平台正则 整串末尾锚点快手/CC 带查询参数时得到空 ID虎牙连字符被截断Twitch 片段进入 ID空路径直接pathSegments.last抖音www空路径抛出Bad state: No element本分支新增的 AcFun 解析与旧逻辑不同本分支新增的 AcFun 解析直接复用WebSearchRoomParser见 web_search_room_parser.dart并保留三条隔离规则非零 UIDAcFun 房间 ID 使用RegExp(r^[1-9][0-9]{0,19}$)拒绝0开头严格路径仅接受live.acfun.cn/live/{id}这种两段路径形态作者页隔离live.acfun.cn/{作者}这类作者主页不视为房间链接。三、红测复现27 个离线用例中的 18 个失败修订前先以确定性离线用例做红测red test记录20260906T234546780Z-quality-focused.json27 个离线用例中 9 通过、18 失败耗时 165.301 秒结束时活跃重型进程 0。日志保存在local-artifacts/live-url-parser-red-20260907.log。审计特别强调18 是失败用例数不是独立 Bug 数——同一根因可能覆盖多个用例。红测复现的失败模式可归为三组第一组协议/主机形态识别失败大写协议/主机未识别如HTTPS://、WWW.虎牙链接中的连字符被截断ID 提取不完整快手链接带查询参数、ID 含下划线/连字符时得到空 IDCC 链接带查询参数得到空 IDTwitch 链接的片段fragment部分进入房间 ID。第二组链接定位与误判首个无关链接遮蔽后面的 AcFun 房间相似域名被误判子域边界判断不严谨未知主机的查询参数里嵌入的虎牙地址被当成第二个链接提取含 userinfo如https://user:passhost/...的输入被误判伪装虎牙后缀的地址得到空 ID 与平台的半有效结果。第三组空路径与非法输入抖音www空路径抛出Bad state: No element对应旧实现pathSegments.lastTwitch directory、虎牙 search、FTP 输入未被正确排除其他平台的空路径返回半有效结果。四、修订方案先提取完整 URL再核对主机与路径修订后的核心思想是剪贴板识别和手动解析共用同一套 HTTP(S) URI 提取逻辑先分离出完整 URL再核对主机及路径绝不从未知主机的查询参数里提取第二个嵌套链接。4.1 统一 URI 提取sharedHttpUrls修订后新增静态方法sharedHttpUrls/sharedHttpUris见 live_url_tool.dart取代旧的第一个正则命中// 提取完整 HTTP URL 后再检查 host/path避免把 FTP URL 内嵌的 // www 地址误当成第二个 HTTP 链接。 static IterableUri sharedHttpUris(String text) sharedHttpUrls(text).map(Uri.parse); static IterableString sharedHttpUrls(String text) sync* { final urls RegExp(r(?:[a-z][a-z0-9.-]*://|www\.)[^\s], caseSensitive: false); for (final match in urls.allMatches(text)) { var candidate match.group(0)!; if (candidate.toLowerCase().startsWith(www.)) candidate https://$candidate; // ... 尾部标点清理含 XHS/微博中文散文粘连处理... final uri Uri.tryParse(candidate); if (uri null || uri.userInfo.isNotEmpty || uri.host.isEmpty || (uri.scheme ! http uri.scheme ! https)) { continue; // 排除 userinfo、非 HTTP(S)、空主机 } // Uri.tryParse 校验百分号转义语法但解码后的访问器仍可能因 // 非法 UTF-8如 /%FF抛出 FormatException逐层排除。 try { uri.pathSegments; uri.queryParametersAll; } on FormatException { continue; } yield candidate; } }这套提取器解决了红测中的多类问题支持无协议www.开头自动补https://前缀支持分享末尾标点对。、》」』”’及 ASCII 标点统一清理尾部排除 userinfo、非 HTTP(S)、空主机/空路径与畸形路径编码/%FF这类非法 UTF-8 会被pathSegments/queryParametersAll的FormatException挡住不从未知主机的查询参数里提取第二个嵌套链接——FTP://...www...这类场景不再产生误提取对小红书xhslink.com / xiaohongshu.com和微博weibo.com分享保留特殊的中文散文粘连处理在中文标点处截断并清理尾部标点同时保留/.、/..这类属于 URL 结构而非散文标点的路径组件。4.2 主机判断与 ID 边界修订后的主机判断不再依赖整串contains而是按完整根域或点分隔子域判断_hostIs(host, root)等价于host root || host.endsWith(.$root)且查询/片段不参与房间 IDstatic bool _hostIs(String host, String root) host root || host.endsWith(.$root);抖音www空路径的崩溃也得到修复_douyinWebRoomId见 live_url_tool.dart只接受恰好一个非空路径段且为 1~20 位数字的形态/video/{id}回放与/search/{query}结果页的尾部数字不再被当作直播房间 ID。4.3 按文本顺序寻找首个可解析目标修订后的_parseLiveUrl见 live_url_tool.dart按文本出现顺序遍历sharedHttpUrls提取出的每个候选逐个尝试平台解析只有当前候选完全无法解析时才继续下一个。这样首个无关链接不再遮蔽后续的 AcFun 房间。4.4 优先复用 WebSearchRoomParser 的平台规则手动解析优先调用WebSearchRoomParser.parse(realUrl)见 web_search_room_parser.dart该解析器统一覆盖了 niconico、Kilakila、小红书、微博、Missevan、Inke、Picarto、TwitCasting、Showroom、CHZZK、17LIVE、LiveMe、TikTok、YouTube、Bigo、PandaLive、FC2、SteamBroadcast、京东直播、酷狗直播、百度直播、六间房、LOOK 直播以及虎牙、抖音、斗鱼、快手、CC、bilibili、Twitch、SOOP、YY、AcFun 的网页房间形态。保留导航词检查是其中的关键_reservedSegmentsweb_search_room_parser.dart收录了search、category、categories、directory、directories、game、games、video、videos、user、users、index、topic、topics、downloads、settings、login、signup等词。任何平台首页/分类/搜索/档案页的 URL即使路径首段长得像房间 ID也会因命中保留词而被拒绝——这直接对应红测中Twitch directory、虎牙 search 未被正确排除的修复。isRoomIdentifier被提取为公共方法见 web_search_room_parser.dart供containsSupportedLink复用原搜索规则保持不变。4.5 手动工具保留的兼容别名入口在WebSearchRoomParser之外手动解析保留了几个不暴露给网页搜索解析器的兼容入口live_url_tool.dart斗鱼/CC 别名www.douyu.com含douyu.com子域与cc.163.com的首段快手cn域live.kuaishou.cn/u/{id}SOOPcom域sooplive.com网页搜索解析器只认sooplive.co.kr系bilibiliwww域www.bilibili.com/{数字}区别于live.bilibili.com抖音回放形态webcast.amemv.com/douyin/webcast/reflow/{id}的reflow数字段。这些入口均通过isRoomIdentifier校验后才能返回半有效结果被杜绝。4.6 翻译资产补上 AcFun 房间格式中英文支持说明同步补充了 AcFun 房间格式见 assets/translations/zh.json 与 assets/translations/en.json 的toolbox_support_contentAcFun直播: https://live.acfun.cn/live/123456审计明确提醒示例地址只是格式说明不是在线房间证据。4.7 抖音的保守边界抖音www/video与webcast reflow用例只锁定已有 ID 提取行为内部room_id与web_rid的真实转换、视频页是否具备直播身份仍待接口证据不据此宣称播放成功。五、回归门禁75/75 → 93/94 → 94/945.1 首次修订75/75 通过首次修订后定向回归75/75 通过构成如下类别数量URL 输入27 项既有网页搜索3 项链接检测containsSupportedLink31 项剪贴板/页面回归14 项记录20260906T234902234Z-quality-focused.json耗时 140.818 秒结束时活跃重型进程 0。5.2 扩展门禁44 项 URL 输入 2 项翻译说明随后扩展为44 项 URL 输入和 2 项翻译说明检查。URL 用例通过HttpOverrides记录并阻止所有网络尝试覆盖未知主机嵌套短链空短链路径畸形编码非法百分号转义/非法 UTF-8多个链接的顺序与兼容别名。全程没有请求任何真实平台。扩展门禁20260907T000046539Z-quality-focused.json为93/94唯一失败用例是中文弯引号结尾——提取器的尾部标点集合漏了弯引号补齐后重新复测不跳过用例。该次flutter analyze有 1 条大括号风格提示360.2 秒一并补齐。过程记录说明该记录耗时 620.609 秒且结束时仍有 1 个活跃重型进程不作为最终通过证据后续20260907T000310949Z-quality-focused.json在格式检查阶段停止按资源守卫格式化变更文件后重跑门禁。最终证据如下。5.3 最终源码结果94/94 定向测试通过44 项直接 URL 2 项翻译说明 3 项网页搜索 31 项链接检测 14 项剪贴板/页面交互flutter analyze无诊断249.3 秒记录20260907T001156727Z-quality-focused.json基于96c5ad55的修订工作树耗时 461.445 秒结束时活跃重型进程 0日志local-artifacts/live-url-parser-final3-20260907.log。资源门禁串行运行遇到其他项目的活跃 Java 进程时等待而非终止。审计同时声明边界仅完成定向源码门禁不等同全量回归、APK 或原生构建通过。六、关键源码解读解析调用链与超时/取消契约6.1 从工具箱到解析器的调用链以跳转房间为例完整调用链为ToolBoxPage的按钮回调调用controller.jumpToRoom(text, context: context)toolbox_controller.dartjumpToRoom进入_runAction的ActionScope超时默认 12 秒见 toolbox_controller.dart_resolve调用parseLink ?? LiveUrlTool.parseLiveUrl(text, cancelToken: scope.cancelToken)解析结果[roomId, platform]需通过Sites.isSupported校验才组装LiveRoom并跳转。获取直链getPlayUrl走同一_resolve随后进入LiveDirectLinkFlow.run见 direct_link_flow.dart依次执行getRoomDetail→discoverPlayQualities→ 用户选择清晰度 →resolvePlayUrls→ 用户选择线路 → 复制。用户选择环节不受超时限制timed: false只有网络/平台操作才被计时。6.2parseLiveUrl的短链会话契约parseLiveUrl每次调用创建一个LiveShortLinkSession见 live_short_link_session.dart专属客户端clientFactory必须返回全新 Dio 客户端绝不使用应用 HTTP 单例总期限connect/send/receive 均设为传入的timeout默认 12 秒Future.timeout到期主动取消并强制session.close()请求预算单次解析最多8 次 HTTP 请求配合已访问 URL 集合防止循环片段fragment不改变网络请求身份幂等释放成功、失败、超时都在finally中ownedCancel.cancel()session.close()迟到结果由关闭状态挡住见 live_url_tool.dart。这套契约正是对旧实现b23 递归新建 Dio 无访问集合/跳数/总期限、抖音自动跟随 maxRedirects100、临时客户端不 close等问题的回应。需要说明该契约属于后续 直播短链接请求边界审查2026-09-07 的完成范围138/138 通过、analyze 无诊断本批审计仅锁定直接链接解析。七、剩余工作与回滚边界7.1 明确未完成项审计明确声明整个工具箱保持未闭环下一组明确任务b23 重定向循环/深度、相对 Location、请求超时与临时 HTTP 客户端释放、抖音短链映射后由 短链请求边界 完成再下一组工具箱动作重复触发、关闭后的迟到导航、画质/线路选择、取消和复制当前远端辅助函数仍保留旧递归与跳转上限设计本批不声称这些问题已解决Android/Windows 原生体验、播放/录制、全量门禁与发布另行验收已安装的67612cc9APK不包含本批变更。7.2 回滚范围回滚范围为四个源文件/资产与新增测试无持久化格式变化live_url_tool.dartweb_search_room_parser.darttoolbox_controller.dart两份翻译资产assets/translations/zh.json、assets/translations/en.json新增测试回滚会恢复上文已复现的直接链接解析问题。八、结论与后续批次状态本批审计把 pure_live 工具箱的直播链接解析从首链接 整串 contains 逐平台正则重构为HTTP(S) URI 提取 主机/路径核对 文本顺序首个可解析目标的契约并通过 94/94 定向测试与无诊断的flutter analyze锁定行为。仓库中的当前实现live_url_tool.dart、web_search_room_parser.dart即为该批修订的最终落地形态相关回归用例可参考 test/shared/platforms/xiaohongshu_link_test.dart小红书分享文本提取的既有契约测试以及审计日志中记录的定向门禁。后续状态请见 直播短链接请求边界审查2026-09-07完成跳转/期限/资源释放/loopback IO138/138 通过与 工具箱剪贴板与页面入口审查2026-09-07剪贴板生命周期65/65 通过。真实平台条件、工具箱操作与原生验收仍独立待验——解析通过不等于平台在线、更不等于播放成功这是整个审计链反复强调的证据边界。赞分享音视频直播移动开发【免费下载链接】pure_live纯粹直播:哔哩哔哩/虎牙/斗鱼/快手/抖音/网易cc/YY直播/Twitch直播/SOOP直播/M38自定义源应有尽有。项目地址https://gitcode.com/gh_mirrors/pur/pure_live点击查看免费下载相关推荐六间房直播接入合同全解析pure_live 的链接、目录、搜索、房间与媒体契约核查六间房直播接入合同全解析pure_live 的链接、目录、搜索、房间与媒体契约核查 本文基于 pure_live 仓库中的 六间房直播合同检查点文档 http音视频直播移动开发Zettlr 链接解析机制深度解析从 Markdown 链接到绝对 URI 的完整技术实现Zettlr 链接解析机制深度解析从 Markdown 链接到绝对 URI 的完整技术实现 导读 在 Zettlr 这类以 Markdown 为核心的知识管理桌面应用前端知识管理科研Pulse v6 API 契约体系解析从接口契约到源码实现的运维监控全链路Pulse v6 API 契约体系解析从接口契约到源码实现的运维监控全链路 Pulse 是一个自托管的实时监控看板覆盖 Proxmox VE、PBS、Doc可观测性运维后端创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
阅读完成 · 觉得有帮助?
咨询建站