ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Ani 动漫资源聚合拆解:多数据源检索的完整管线

Ani 动漫资源聚合拆解:多数据源检索的完整管线

Ani 动漫资源聚合拆解:多数据源检索的完整管线

【免费下载链接】animation-garden集找番、追番、看番的一站式弹幕追番平台,云收藏同步 (Bangumi),离线缓存,BitTorrent,弹幕云过滤。100% Kotlin/Compose Multiplatform项目地址: https://gitcode.com/gh_mirrors/an/animation-garden

你正在追一部新番,更新日一过,浏览器里同时开着三个标签页:动漫花园一个、蜜柑一个、自己的 RSS 一个,来回翻着找质量最高的那一份。Ani(Animeko)把这活儿收进了应用内部,靠的是一套动漫数据源聚合机制:一次搜索,多个源并发查询,结果统一交到你手上。

一次搜索背后发生了什么

把"点下搜索"到"列表出现"的过程拆开,是四拍:

  • 请求:你输入关键词,请求先落到聚合入口,这里不碰任何具体网站,只负责把查询包装成统一结构。
  • 分发:分路器把同一个查询并行发往每个已启用的源适配器。某个源慢,不拖累其他源。
  • 归一:各源返回的东西外表不同——RSS 是 XML,动漫花园是 HTML。适配器各自把它们揉成同一种Topic结构:标题、大小、字幕组、下载链接,字段对字段。
  • 排序:归一化之后给每条结果打标——命中强度是EXACT还是FUZZY、所在源的 tier 数值、标题里是否带集数——评分器据此给出最终列表。

所有源共用的骨架是 HttpMediaSource 基类:它只管连接生命周期与资源释放,具体源只需要回答"怎么搜"和"怎么解析"两个问题。

三个源各有什么脾气

动漫花园是内地字幕组的主阵地,多数热门番在这里最先落地。资源体量在十万颗上下,全天都在滚动更新。它的小亮点在标题解析:字幕组、集数、文件大小都能从原始标题里直接抽出来,不额外请求详情页,列表就已经很齐整。

蜜柑是海外站里最稳的一个,新番上线通常在播出后一到两小时内跟上。资源体量也在十万颗量级,日本系资源占优。最有意思的是它不靠关键词起手:先拿 Bangumi 的番剧 ID 去换 Mikan 自己的 ID,再直接取那部番的 RSS,省掉模糊匹配。

RSS 是留给玩家的一张 wild card。更新频率和资源体量都由你接的站点决定,接得越多网撒得越大。它独有的地方是订阅机制:别人的源配置可以整包导入分享,一条订阅就能把整列源补齐。

💡 源码里的两处巧思

探活不吞取消。点在于把"用户主动取消"和"站点真的挂了"分开处理,前者不能被后者掩盖。

override suspend fun checkConnection(): ConnectionStatus { return try { network.list() ConnectionStatus.SUCCESS } catch (e: CancellationException) { throw e // 取消不是失败, 继续上抛 } catch (e: Exception) { logger.error(e) { "Failed to check connection" } ConnectionStatus.FAILED } }

→ 完整实现见 动漫花园数据源

ID 映射缓存加兜底。同一部番第二次搜索时跳过查名环节,直接走 Bangumi RSS;映射没命中就退回关键词搜索,链条不断。

val subjectId = indexCacheProvider.getMikanSubjectId(bangumiSubjectId) ?: request.subjectNames .firstNotNullOfOrNull { findMikanSubjectIdByName(it, bangumiSubjectId) } ?.also { indexCacheProvider.setMikanSubjectId(bangumiSubjectId, it) } ?: return null return client.prepareGet("$baseUrl/RSS/Bangumi?bangumiId=$subjectId") .body<ByteReadChannel>().toSource().use { parseRssTopicList(Xml.parse(it, baseUrl)) }.map { MediaMatch(it.toOnlineMedia(mediaSourceId), MatchKind.EXACT) }

→ 完整实现见 蜜柑索引缓存

🛠 动手:五分钟调出你喜欢的源

  1. 打开"设置",进入"数据源管理"页签。
  2. 点"添加数据源",从模板里挑一个:动漫花园、蜜柑或 RSS。
  3. 在新源的编辑页里点"测试数据源",确认探活通过。
  4. 调整 tier 数值:越小越优先,阶级 0 的源查到结果会立刻被选用。
  5. 回到播放器打开媒体选择器,新源已经排在位上。

如果想进一步调参,有两个配置字段值得动:tier——常用源给 1,最信任的给 0;filterByEpisodeSort("要求资源标题包含剧集序号")——建议保持开启,能滤掉不少模糊命中。

连不上?结果少?三个高频场景

某源显示"连接失败":当前网络根本到不了那个站点 → 检查"设置"里的网络与代理项,它作用于全部数据源。

搜索没结果或只有一两条:该源的索引没跟上这部番,或者标题过长被截断 → 换 Bangumi 详情页里的检索入口再试,走索引路径的源更可靠。

剧集重复或匹配到错集:源返回的是模糊命中,评分被稀释 → 给该源打开"要求资源标题包含剧集序号"的过滤,让标题里的集数说话。

结尾

完整的多数据源实现都落在仓库的datasource/目录里,每个站点是一个独立模块。想动手加一个站,先把它克隆下来:git clone https://gitcode.com/gh_mirrors/an/animation-garden。工厂模板都在,你心里那个源的位置,已经留出来了。

【免费下载链接】animation-garden集找番、追番、看番的一站式弹幕追番平台,云收藏同步 (Bangumi),离线缓存,BitTorrent,弹幕云过滤。100% Kotlin/Compose Multiplatform项目地址: https://gitcode.com/gh_mirrors/an/animation-garden

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

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进