
Animeko 数据源整合五类源如何协同【免费下载链接】animation-garden集找番、追番、看番的一站式弹幕追番平台云收藏同步 (Bangumi)离线缓存BitTorrent弹幕云过滤。100% Kotlin/Compose Multiplatform项目地址: https://gitcode.com/gh_mirrors/an/animation-garden播放页起播一集之前Animeko 会并行向蜜柑计划、dmhy、Jellyfin 以及自配的多个网站发起数据源查询再把全部结果交给同一个选择器挑出最合适的资源。你不需要知道资源来自哪个站点。核心价值速览项目内容解决什么动漫资源分散在多个站点同一部番需逐站手工搜索页面结构与结果质量各不相同工作方式每个站点封装在统一的 MediaSource 接口之后由选择器对全部源的做过滤、排序与自动选择适用场景WEB 在线直连、BT 种子下载、Jellyfin/Emby/Ikaros 本地媒体库前置依赖条目数据由 Bangumi 提供内置源随应用就绪自定义源需编写 CSS Selector 或 JSONPath快速上手安装应用后打开任一作品播放页内置数据源蜜柑计划、dmhy、Jellyfin、Emby、Ikaros默认即参与首次查询。打开「设置 → 数据源管理」查看源列表用开关启停某个源并用测试按钮验证站点连通性。新增站点选择「Selector」类型为搜索页、条目页、播放页分别编写 CSS Selector如以 acg.rip 为例配置好搜索与剧集列表规则经内置测试面板通过后再保存。若站点数据全部走 JSON 接口改选「JSON API」类型为搜索、条目剧集、播放地址三个阶段各配置请求模板与 JSONPath 表达式。想直接复用他人配置时导入订阅文件其中的数据源会批量导入并可按订阅整体启停。原理拆解数据源只负责把资源列出来接口层无论 WEB 还是 BT 站点都实现同一个 MediaSource。核心方法fetch接收一个MediaFetchRequest返回该条目在本源上的全部可下载资源。请求携带 Bangumi 条目 ID、条目全部已知名称与完整剧集列表结果中的每个资源带MatchKind标记按条目 ID 精确定位为 EXACT按关键字搜到为 FUZZY。数据源不裁剪剧集按集筛选由选择器完成。源由工厂声明并动态加载应用不硬编码源实例。工厂MediaSourceFactory声明 factoryId 与可配置参数按配置创建实例。MediaSourceManager初始化时的这段代码枚举了应用可识别的全部源SPI 部分用于模块化的第三方源内置源逐个补齐。private val factories: ListMediaSourceFactory buildSet { addAll(ServiceLoader.loadServices(MediaSourceFactory::class)) add(MikanMediaSource.Factory()) add(MikanCNMediaSource.Factory()) add(RssMediaSource.Factory()) add(JellyfinMediaSource.Factory()) add(EmbyMediaSource.Factory()) add(IkarosMediaSource.Factory()) add(SelectorMediaSource.Factory(selectorMediaSourceEpisodeCacheRepository, webSessionManager)) add(JsonApiMediaSource.Factory(selectorMediaSourceEpisodeCacheRepository)) }.toList()配置变化会重建对应源实例代理设置变化同样触发重建因此换网络配置无需重启应用。Mikan 的两段式查询与索引缓存Mikan 展示了比裸关键字搜索更快一条路的写法先把 Bangumi 条目 ID 映射成 Mikan 的条目 ID直接查该条目的 RSS映射查不到才回退到关键字搜索。private suspend fun HttpClient.searchByIndexOrNull(request: MediaFetchRequest): ListMediaMatch? { val subjectId indexCacheProvider.getMikanSubjectId(request.subjectId) ?: request.subjectNames.firstNotNullOfOrNull { findMikanSubjectIdByName(it, request.subjectId) } ?.also { indexCacheProvider.setMikanSubjectId(request.subjectId, it) } ?: return null return client.prepareGet($baseUrl/RSS/Bangumi?bangumiId$subjectId).bodyByteReadChannel().toSource().use { parseRssTopicList(Xml.parse(it, baseUrl), baseUrl) }.map { MediaMatch(it.toOnlineMedia(mediaSourceId), MatchKind.EXACT) } }映射先查缓存未命中时搜索站点并从条目页读回 Bangumi 链接校验后写回缓存同一条目下次查询直接走缓存。应用内该缓存由 DataStore 持久化重启不清空。全部源查询完成后才做选择选择器分过滤、排序、偏好、选择四个阶段。每个数据源有一个阶级MediaSourceTier数值越小优先级越高tier 为 0 的 WEB 源在查询完成且命中精确匹配时会被立即选中不用等其他源。进阶配置与调优以下参数写在数据源的 arguments 中随订阅文件分发时旧版本客户端会忽略不认识的新字段配置项位置作用推荐值tier源 arguments数据源阶级数值越小排序越靠前并参与快速选择可信优质源设 0未配置时默认 2channelTiers源 arguments按线路名覆盖源整体阶级常用线路设为 0autoMatch.searchUseSubjectNamesCountSelector 源 searchConfig依次尝试搜索的条目名数量2requestIntervalJSON API 源配置三个阶段请求共用的最小间隔即源级限流500 mstier 同时影响两个环节排序阶段按有效阶级channelTiers[线路名] ?: 源 tier决定先后快速选择阶段按阈值判断能否立即选中。一个 tier 较高的源若拥有 tier 0 的线路该线路资源仍可被立即选中。避坑指南完结番的 BT 源只见整季合集、不见单集。原因是默认开启的「完结番隐藏单集资源」会剔除完结条目的单集资源。解法是在播放与缓存的高级设置中关闭对应项或直接选用整季资源节省流量。Mikan 对长名称条目查不到结果。原因是站点搜索无法匹配超过 19 个字的名称源端请求前会截断名字。解法是源端优先走 Bangumi ID 索引映射精确定位缓存未命中才做名称搜索通常自行恢复无需人工干预。升级后的订阅文件被旧版客户端整体拒绝。原因是订阅导出格式带版本号不识别新 schemaVersion 的客户端会拒收整个文件。解法是分发时避免无谓升版本号新字段依赖 ignoreUnknownKeys 机制保持向后兼容。自动选择列表里出现不相关条目的资源。原因是数据源检索基于关键字同名或部分匹配的条目必然进入结果。解法是选择器过滤阶段按条目名剔除手动选择列表中也可直接点选正确资源选择会被记住。延伸阅读docs/contributing/code/media/media-source.md官方数据源文档讲清 fetch 契约、选择器四阶段与 tier 机制写新源或改订阅前的第一站。datasource/api/src/commonMain/kotlin/source/MediaSource.kt接口的 KDoc 给出了「数据源应承诺什么」最完整的定义结果完整性、episodeRange 准确、mediaId 稳定。【免费下载链接】animation-garden集找番、追番、看番的一站式弹幕追番平台云收藏同步 (Bangumi)离线缓存BitTorrent弹幕云过滤。100% Kotlin/Compose Multiplatform项目地址: https://gitcode.com/gh_mirrors/an/animation-garden创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考