跳到架构设计内容

ENGINEERING / ANIMEFLOW

AnimeFlow 架构设计,
读懂每一条播放链路。

一份基于客户端源码的架构设计说明。沿着数据与事件的流向,了解 AnimeFlow 如何连接跨平台界面、可配置数据源、双播放内核、离线下载与收藏同步。

01 / SYSTEM OVERVIEW

以功能为边界,以接口连接。

app 组装应用,features 承载业务,core 提供基础设施,shared 复用模型与组件。下面的图展示模块关系,点击节点可查看职责和对应实现。

客户端系统架构 选择节点查看实现
界面与状态逻辑与接口数据与存储平台与外部服务
客户端系统架构箭头表示主要调用或数据访问方向;网络、存储和平台能力可被多个功能共享。这里展示的是客户端边界,外部服务以接口呈现。监听 / 操作路由参数播放会话任务状态收藏状态统一控制数据读写API / SSE内核适配持久化HTTP 请求Flutter 页面与组件presentation / shared/widgetsRiverpod 状态与会话Provider · Notifier · AsyncValueGoRouter 类型化路由StatefulShellRoute · route extra播放与弹幕业务PlaySession / DanmakuSession下载与视频源业务DownloadManager / RuleEngine账号与收藏业务BgmCollectionSync / repositories播放器领域契约PlayerEngine · Event · Snapshot数据仓库与共享模型Source / Play / Download repositories网络与认证基础设施DioFactory · clients · interceptors跨平台原生适配media_kit / FVP / WebView设备上的持久化Hive CE · secure storage · files外部服务与内容站点Flow / GitHub / trace.moe / sources
箭头表示主要调用或数据访问方向;网络、存储和平台能力可被多个功能共享。这里展示的是客户端边界,外部服务以接口呈现。窄屏可左右滑动查看完整图示。
界面与状态 · 实现说明

Flutter 页面与组件

首页、排行、搜索、番剧详情、播放、下载与用户页面负责展示和交互;共享组件承载番剧卡片、图片与 BBCode 内容。

说明范围:客户端源码及其外部接口。Flow 服务的数据库、任务队列与部署拓扑未包含在此仓库中,因此以外部服务节点表示。

02 / BOOTSTRAP & STRUCTURE

先恢复运行条件,再进入界面。

启动流程把必须完成的存储与平台初始化放在 runApp 之前;在线状态、内置源和 Shader 准备等工作以异步任务启动,减少根组件中的初始化责任。

01

初始化运行环境

main() 以 runZonedGuarded 捕获未处理异常;bootstrap 初始化 Flutter binding、错误日志、许可信息与 MediaKit。

02

恢复本地状态

初始化 Hive 与各业务 Box;iOS 重定位历史下载路径,恢复下载目录权限,接入图片缓存并初始化前台下载服务和字体。

03

准备网络与平台能力

读取包信息并初始化 DioFactory 的设备 User-Agent;异步启动 PresenceService。桌面平台初始化窗口并设置标题栏。

04

创建状态容器并启动 UI

创建 ProviderContainer,读取应用信息,异步准备 Shader 目录与内置数据源;runApp 使用 UncontrolledProviderScope 注入容器。

目录职责与实现入口
源码目录 职责 组织方式
lib/app/应用组装启动流程、应用根节点、类型化路由、主题与本地化。
lib/features/功能模块围绕 home、search、play、download、user、source 等业务组织;按复杂度采用 presentation、application、data、domain、infrastructure。
lib/core/跨功能基础设施网络与认证、规则引擎、平台 WebView、设置、日志、图片缓存及在线状态服务。
lib/shared/共享数据与组件番剧、剧集、下载和收藏模型,以及图片、卡片、BBCode 等通用界面组件。
test/行为验证覆盖纯逻辑、仓库、Provider、内核适配与 Widget 交互,测试目录大体镜像功能结构。

03 / SOURCE PIPELINE

规则驱动,多源检索与媒体解析分离。

番剧元数据与播放站点资源是两类数据。数据源功能把可配置站点转成统一的搜索条目和剧集线路,再通过平台 WebView 提取最终媒体地址,播放器无需理解每个站点的页面结构。

从声明式规则到可播放媒体 选择节点查看实现
界面与状态逻辑与接口数据与存储平台与外部服务
从声明式规则到可播放媒体按箭头从左上沿蛇形阅读。选中搜索候选后,再经 RuleEngine 获取剧集线路;WebView 将选中的剧集页面转换成媒体 URL,规则解析与媒体解析承担不同职责。读取规则准备请求响应内容候选条目匹配排序选集 URLURL / 偏移打开媒体数据源配置CrawlConfigItem / SourceRepository规则执行引擎RuleEngine / strategies站点请求与验证RuleRequest / Cookie / Captcha结构化资源结果HtmlCrawler / ApiCrawler标题匹配与排序SearchResultRankService / Isolate选择站点、线路与剧集VideoSourceNotifier解析剧集播放页面WebViewVideoSourceService可播放的媒体源VideoSource → PlaybackSource开始播放PlaySession.initPlayState()
按箭头从左上沿蛇形阅读。选中搜索候选后,再经 RuleEngine 获取剧集线路;WebView 将选中的剧集页面转换成媒体 URL,规则解析与媒体解析承担不同职责。窄屏可左右滑动查看完整图示。
数据与存储 · 实现说明

数据源配置

插件是声明式 JSON 规则。下载后先校验规则 API 兼容性,再以插件目录版本覆盖规则内版本,保存配置与排序到本地。

01

声明式扩展与兼容性检查

搜索与章节可分别使用 XPath 或 API 规则;API 请求支持 GET/POST、变量模板和 JSONPath 提取。安装时验证 RuleApiLevel,避免把客户端无法执行的规则写入配置。

02

检索并发与标题匹配

站点搜索默认限制为 5 路并发、每站最多 5 个候选。标题与别名在 isolate 中打分,同时考虑季数、最终季、OVA 和剧场版等差异,降低错番和错季的选择概率。

03

解析取消与验证码恢复

站点验证由验证码 WebView 与 CookieManager 配合处理;播放解析服务复用共享 WebView。新请求取消旧请求,身份校验与超时约束共同阻止旧解析结果污染当前集。

查看相关行为测试 4 个源码入口

04 / PLAYBACK SESSION

一套会话,协调内核、状态与观看进度。

播放模块的分层最完整:presentation 负责界面与状态,application 负责业务协调,domain 定义播放器契约,infrastructure 接入 media_kit 和 FVP。弹幕和播放记录与会话协作,各自管理请求与持久化逻辑。

播放命令、内核事件与会话状态 选择节点查看实现
界面与状态逻辑与接口数据与存储平台与外部服务
播放命令、内核事件与会话状态上方是命令链路,中间是内核事件回流;下方是进度保存和弹幕调度。虚线表示关联的旁路业务,媒体播放不依赖弹幕请求成功。操作命令统一调度原生调用事件流更新状态位置 / 时长防抖保存会话调度播放页面与操作player UI / gestures / shortcuts播放会话PlaySession串行命令与内核切换PlaybackCoordinator可替换的播放器内核PlayerEngine → media_kit / FVP统一播放事件PlayerEvent响应式播放状态PlayState / PlaybackPhase观看进度与续播记录PlaybackProgressManager本地记录与远端同步PlayRepository → Hive / Flow API与播放时间同步的弹幕DanmakuSession / Scheduler
上方是命令链路,中间是内核事件回流;下方是进度保存和弹幕调度。虚线表示关联的旁路业务,媒体播放不依赖弹幕请求成功。窄屏可左右滑动查看完整图示。
界面与状态 · 实现说明

播放页面与操作

进度条、触屏手势、桌面鼠标和快捷键发出播放命令。VideoUiNotifier 管理控件显隐及解析指示,不承担原生内核生命周期。

01

内核接口与快照恢复

PlayerEngine 统一打开、seek、音量、倍速、截图与 Shader 操作。切换时从 PlayerSnapshot 恢复媒体和进度,候选内核准备完成后替换事件订阅;能力差异通过 PlayerCapabilities 显式判断。

02

异步竞态与资源生命周期

PlayerOperationQueue 串行化原生操作;PlaySession 用请求 ID 检查切集结果,seek 落点确认前过滤陈旧事件。退出页面时失效请求、取消订阅、保存进度,并等待原生队列排空后释放内核。

03

进度记录与自动标记

记录按 3 秒防抖并串行写入,先落 Hive 再同步 Flow。自动标记已看需满足登录、设置开启、非本地播放、有效番剧与剧集信息、时长至少 2 分钟且播放达到 90%;进行中和已完成的标记请求会去重。

04

弹幕与 Anime4K

弹幕按秒分桶并在该秒内分散发送,seek 或切集立即取消待发计时器。繁简转换有独立版本检查,屏蔽来源和颜色在分发时处理。Anime4K GLSL 从 assets 复制到应用支持目录,仅对支持 Shader 的内核启用。

查看相关行为测试 4 个源码入口

05 / OFFLINE PIPELINE

下载是有状态的任务系统。

离线功能不仅保存一个 URL。它需要解析资源、调度多个剧集、控制分片并发、处理暂停与续传、维护目录权限、持久化任务状态,并让本地文件重新进入统一播放链路。

从下载任务到离线播放 选择节点查看实现
界面与状态逻辑与接口数据与存储平台与外部服务
从下载任务到离线播放主链路展示 HLS 下载;直链媒体绕过播放列表解析进入文件传输。目录权限与下载记录分别管理文件访问和任务状态。解析请求媒体地址检测 HLS分片 / 密钥落盘 / 重写目录访问进度 / 状态完成记录选择下载剧集DownloadProvider独立视频解析池VideoSourceResolverPool剧集任务调度DownloadManagerHLS 播放列表解析M3u8Parser分片 / 直链文件传输DownloadHttpClient / retries可离线播放的文件local playlist / media / danmaku平台目录与权限DownloadDirectoryPlatform下载状态持久化DownloadRepository / Hive离线选集与播放Episodes / PlaybackSource.localFile
主链路展示 HLS 下载;直链媒体绕过播放列表解析进入文件传输。目录权限与下载记录分别管理文件访问和任务状态。窄屏可左右滑动查看完整图示。
界面与状态 · 实现说明

选择下载剧集

下载状态层协调资源解析、任务管理、弹幕保存与 UI 更新;暂停、续传、删除和优先任务通过管理器接口执行。

01

分层并发与可取消任务

VideoSourceResolverPool 负责解析 worker;DownloadManager 负责剧集队列;信号量限制每集分片传输。管理器默认 2 集、每集 3 分片并发,实际配置可由设置调整。Android 另接入前台服务维护下载通知与后台任务。

02

HLS 的本地重建

解析主列表、相对地址、嵌套列表、密钥、初始化段和字节范围,下载后重写本地 m3u8;嵌套解析深度默认最多 3 层。流程明确拒绝直播和独立音轨,避免生成不完整的离线内容。

03

续传、状态与离线复用

已完成的 HLS 分片可复用,直链文件按 Range 续传,传输失败按 1/3/9 秒退避。进度缓存在内存、状态改变时写 Hive;已完成记录构建离线剧集列表,本地媒体和弹幕复用原有播放器会话。

查看相关行为测试 4 个源码入口

06 / COLLECTION SYNC

以任务版本为准,让实时同步保持有序。

收藏同步由客户端触发 Flow 服务的任务,再以 SSE 订阅进度和冲突状态。账号变化、页面订阅和应用前后台都会影响连接生命周期;客户端只接受当前会话的有效更新。

收藏同步任务的客户端生命周期 选择节点查看实现
界面与状态逻辑与接口数据与存储平台与外部服务
收藏同步任务的客户端生命周期HTTP 发起操作,SSE 回传任务状态;前台订阅范围决定连接是否存在,心跳和退避控制恢复过程。冲突通过单独的用户操作解决。确认绑定HTTP 操作推送状态解码模型有效变化连接条件心跳 / 断线冲突交互账号登录与 Bangumi 绑定FlowToken / bangumiBindProvider查询 / 触发 / 解决冲突CollectionSyncRepositoryFlow 同步任务接口HTTP status / trigger / conflicts增量 SSE 状态流UTF-8 → lines → event frames有序接收任务状态taskId / statusVersion / generation刷新收藏与番剧页面invalidate / collectionRevision前台与页面订阅范围ConnectionScope.owners心跳与断线重连60 s heartbeat / 1–30 s backoff用户处理收藏冲突CollectionConflictsDialog
HTTP 发起操作,SSE 回传任务状态;前台订阅范围决定连接是否存在,心跳和退避控制恢复过程。冲突通过单独的用户操作解决。窄屏可左右滑动查看完整图示。
界面与状态 · 实现说明

账号登录与 Bangumi 绑定

同步状态 Provider 先等待 Flow 登录令牌,再确认 Bangumi 已绑定。应用启动或进入前台发现任务状态;触发同步是独立的显式操作。

01

状态发现与任务触发分离

登录并完成 Bangumi 绑定后读取同步状态。CollectionSyncLifecycle 负责启动与前台恢复时发现状态,启动本身不会发起同步;用户操作经仓库提交带请求 ID 的触发请求。

02

增量解码与过期状态过滤

SSE 解析处理跨块 UTF-8、多行 data、注释心跳与空行分帧,单事件文本限制 64 KiB。任务 ID 和 statusVersion 保证新状态不会被旧状态覆盖,generation 隔离已结束的连接与登录会话。

03

订阅范围、重连与冲突

前台且存在页面订阅者时才保持连接;60 秒无事件触发断线处理,重连按指数退避、上限 30 秒。有效同步变化刷新收藏并递增 revision;收藏冲突通过对话框读出差异,由用户选择后单独提交。

查看相关行为测试 4 个源码入口

07 / SHARED INFRASTRUCTURE

完整体验,来自共同的基础设施。

账号、网络、缓存、平台与更新贯穿多个功能。将这些能力放在独立入口中,让业务页面保持清晰,也让异常恢复有一致的处理位置。

账号认证与会话保护

邮箱登录由 LoginService 写入 FlowTokenStorage,令牌保存在 FlutterSecureStorage。刷新拦截器仅在明确的 access_token_expired 情况下处理,多个请求共享刷新 Future,每个原请求最多重试一次;退出登录使旧刷新代次失效,临时网络或存储失败不会直接清空有效会话。

查看实现文件lib/features/auth/application/login_service.dartlib/core/auth/repository/flow_token_storage.dartlib/core/network/interceptors/flow_refresh_token_interceptor.dart

发现、识番与应用更新

首页、排行、日历、搜索、人物和番剧详情以各自 Provider 加载业务数据;截图识番将图片文件或 URL 交给 trace.moe。更新检查经 FlowApi.getLatestRelease 获取发布信息,再由平台更新控制器处理下载后的安装或跳转。功能模块复用共享模型与网络服务。

查看实现文件lib/core/network/api/api.dartlib/features/app_update/application/app_info_provider.dartlib/features/app_update/application/apply_updates_controller.dart

08 / DESIGN & VERIFICATION

把复杂性留在明确的边界里。

功能内聚、接口隔离、异步失效检查与持久化策略贯穿这些实现。现有测试覆盖规则解析、内核切换、弹幕调度、下载恢复和收藏同步等行为,可从各章节的测试入口继续阅读。

01

按功能组织,按复杂度分层

功能目录形成业务边界,播放等复杂模块再细分领域与适配层。较轻的模块直接以页面和 Provider 组织;这种渐进分层让结构与功能复杂度相匹配,减少简单业务中的层级负担。

02

接口隔离原生与外部依赖

PlayerEngine、IVideoSourceProvider、IDownloadManager 与 IDownloadRepository 为替换内核、注入测试实现和平台适配提供边界。数据源规则把站点差异从播放器控制逻辑中移出。

03

为异步结果定义有效期

播放请求 ID、弹幕 generation/epoch、收藏任务版本和认证刷新代次处理各自的竞态;串行队列管理不能并发的原生操作,取消令牌管理可终止的网络请求。

04

分清实时状态与持久状态

UI 与高频下载进度保留在响应式状态或内存缓存中;Hive 保存恢复所需记录,媒体保存在文件系统,认证凭证进入安全存储。播放记录先本地保存,再尝试同步。

回到页面顶部 ↑