【免费下载链接】ARVIO
ARVIO - A media hub application with a modern, beautiful interface.
ARVIO 是一个开源媒体中心(media hub),用 Kotlin + Jetpack Compose 构建 Android/Android TV 客户端,用 Next.js 构建可自托管的 Web 端,通过 Supabase 云同步打通手机、平板、电视与浏览器。本文带你拆解这个 monorepo 的完整架构:分层代码组织、播放内核、跨端一致性机制与工程化质量体系,适合想学习大型 Android + Web 混合项目架构的开发者。
一、ARVIO 全景:一个仓库承载整个媒体中心
ARVIO 采用 monorepo 组织方式:settings.gradle.kts 只声明了:app与:benchmark两个 Gradle 模块,其余能力由不同技术栈的独立目录承担。这种"多技术栈、单仓库"的结构是理解它架构的钥匙:
| 目录 | 技术栈 | 职责 |
|---|---|---|
| app/ | Kotlin + Jetpack Compose | Android 手机 / Android TV / Fire TV 客户端 |
| web/ | Next.js 15 + React 19 | 浏览器媒体中心,支持自托管 |
| supabase/ | TypeScript Edge Functions | 云认证、账号同步、第三方代理 |
| netlify-auth-site/ | Node.js Functions | Web 端认证与会话后端 |
| resolver-worker/ | Cloudflare Worker (TS) | 流地址解析 |
| benchmark/ | Android Macrobenchmark | 生成 Baseline Profile 优化启动性能 |
二、Android 端:Kotlin + Jetpack Compose 打造 TV 体验
2.1 技术栈:Kotlin 2.x 与 Compose 编译器
app/build.gradle.kts 中的插件清单揭示了核心选型:org.jetbrains.kotlin.plugin.compose(Kotlin 2.0 起 Compose 编译器独立成插件)、com.google.dagger.hilt.android(Hilt 依赖注入)、androidx.baselineprofile(TV 流畅度优化)与detekt(静态检查)。
几个值得注意的细节:
- 兼容性:
minSdk = 23是为了覆盖 Android 7.1 甚至更老的 Fire TV 设备,targetSdk = 36。 - 渠道风味(Product Flavor):build.gradle.kts 定义了
play与sideload两种分发包——sideload 版本额外启用插件系统(QuickJS 嵌入式 JS 引擎)、端侧语音识别(sherpa-onnx)与自更新。 - 一次真实的架构决策:settings.gradle.kts 里保留了一段注释,解释为何锁定 R8 9.5.28——旧版 R8 在 release 构建中错误优化播放器类导致
VerifyError崩溃,debug 构建因不跑 R8 而无法复现。这类"踩坑留痕"注释是开源项目架构演进的绝佳教材。
2.2 分层代码组织:500+ 个 Kotlin 文件的分工
主代码位于 app/src/main/kotlin/com/arflix/tv/,共 500+ 个.kt文件,按职责分为 14 个包:
| 包 | 职责 | 代表文件 |
|---|---|---|
data/ | API 客户端、本地存储、Repository 层 | CatalogRepository.kt |
domain/model | 业务领域模型 | MediaItem、MediaType |
ui/ | Compose 屏幕、组件、主题、焦点系统 | HomeScreen |
navigation/ | NavHost 路由与动画 | AppNavigation.kt |
di/ | Hilt 依赖注入装配 | AppModule.kt |
worker/ | WorkManager 后台任务 | CloudSyncWorker.kt |
player/ | 播放内核与杜比视界处理 | DolbyVisionStripTransformer.kt |
这是典型的 MVVM + Repository 分层:ui/screens中的 Composable 通过hiltViewModel获取 ViewModel,ViewModel 只依赖data/repository接口,navigation/负责把 Home、Details、Player、LiveTv 等 12 类屏幕接成路由图。
2.3 播放内核:Media3、杜比视界与原生代码
播放层基于Media3/ExoPlayer全家桶(exoplayer、HLS、DASH、session、effect),并针对电视场景做了深度定制:
- 杜比视界降级链:
player/dv/下的HevcDvRpuStripper、HevcHdr10PlusStripper等类可在解码前剥离 DV RPUs,让不支持的设备也能播放; - 内嵌原生组件:app/src/main/ 还包含
dvmkv-java(vendored 版 Media3 Matroska 解析器)、iptvts-java(IPTV 时间戳处理)、tdlib-java(Telegram 媒体搜索)与jniLibs,通过 NDK 28 编译为 arm64/armeabi 原生库,并支持 16KB 内存页。
三、Web 端:Next.js 15 构建可自托管的媒体中心
3.1 App Router 与 API 路由
web/package.json 显示 Web 端使用 Next.js 15 + React 19 + TypeScript,并引入hls.js、dashjs、mpegts.js、mp4box、mediabunny一整套浏览器流媒体解码库。
App Router 下,页面与接口按目录自然分离(见 web/app/):
- 页面路由:
/login、/migrate、/report、/dev等; - API 路由:web/app/api/ 包含
tmdb、trakt、simkl、mdblist、cloud-auth、proxy、subtitle等 8 组路由——第三方 API Key 留在服务端,浏览器只访问自家路由,这是自托管安全性的关键设计。
3.2 浏览器播放与状态管理
浏览器端最大的难题是编码兼容性。ARVIO 的解法在 web/lib/ 的 100+ 个 TS 模块中:
- Web Worker 转封装:remux.worker.ts 在后台线程对 MP4/EBML 做重封装,配合
ts-ebml、mp4box让 iOS Safari 也能播放; - 杜比视界探测:
dolbyVisionProbe.worker.ts+dolbyVisionMetadata.ts在浏览器中解析 DV 元数据; - 细粒度状态存储:web/lib/store/ 将状态拆成 18 个独立 store(
playback、iptv、library、profiles、settingsSync等),避免单一全局 store 引发的整页重渲染。
3.3 自托管与国际化
通过 Docker Compose 一键部署(web/compose.yaml),仅需自备 TMDB API Key 即可运行(web/README.md 有完整指南)。国际化方面,web/public/i18n/ 提供 56 种语言包,覆盖西班牙语、葡萄牙语等市场。
四、云同步与后端:藏在 Supabase 里的架构
跨设备"进度、观看列表、设置处处一致"的能力来自 supabase/functions/ 的 Edge Functions:tv-auth-start/status/complete/approve实现了类似"电视扫码登录"的授权流,trakt-proxy、simkl-proxy、tmdb-proxy则把第三方 API 收敛到服务端。
数据库层由 supabase/migrations/ 中的 SQL 演进而来,关键迁移包括:
20260211_tv_auth_and_account_sync.sql—— TV 授权与账号同步表结构;20260618_account_delta_sync.sql——增量(delta)同步:设备只上传变更而非全量状态,这是低流量跨端同步的核心;20260525_app_usage_analytics.sql—— 匿名使用分析。
五、跨端一致性:同一媒体中心如何"长"得像
多端体验一致靠的是三层机制:
- 共享数据源:web/lib/defaultCatalogs.json 直接由 Android 端的
buildPreinstalledDefaults导出,保证两端内置目录(trending、热门剧集等)完全一致; - 云同步:
CloudSyncWorker(Android)与settingsSync.ts(Web)围绕 delta 同步协议交换状态,supabase的 realtime channel 做即时失效通知; - 第三方追踪器:Trakt / SIMKL 按 Profile 连接,为 Continue Watching、下一集推荐提供统一的数据底座。
Live TV 是跨端一致性的最佳展示——Web 端同样实现了 13 万+ 通道的 EPG 节目单、分组与收藏:
六、工程化质量:monorepo 如何保持长期稳定
- Android 测试:app/src/test/ 含 332 个单元测试文件,
androidTest含 96 个 instrumentation 测试(Espresso + Compose UI Test),测试栈覆盖 MockK、Turbine、Robolectric; - Web 测试:
node --test驱动的 80+ 个.test.cjs契约测试 + Playwright E2E,另有一批check-*-ui.cjsUI 守护脚本(见 web/scripts/); - 静态检查:Android 端 detekt(config/detekt/detekt.yml)、Web 端 ESLint;
- 性能预算:
:benchmark模块生成 Baseline Profile 随 APK 分发,TV 冷启动与帧率有实测指标(docs/navigation-performance-2026-09-29.md)。
想本地构建或自托管?Android 端用 Android Studio 打开 app/ 即可(sideload 版需-PincludeX86Abis等选项按需调整);Web 端克隆仓库后按官方指南操作:
git clone https://gitcode.com/gh_mirrors/ar/ARVIO cd ARVIO/web npm ci npm run setup:selfhost七、总结:这套架构的 5 个可复用模式
| 模式 | ARVIO 的做法 |
|---|---|
| monorepo 分栈 | Android/Node/Edge Function 各占一目录,互不污染构建 |
| 分层清晰 | data → domain → ui + Hilt,500 个文件不失控 |
| 渠道风味 | play/sideload 用 buildConfigField 开关能力,一套代码两种发行 |
| 跨端数据契约 | JSON 目录由 Android 导出给 Web,单一事实来源 |
| 踩坑留痕 | 关键版本锁定都附注释说明原因与验证方法 |
ARVIO 证明了:开源媒体中心不必是单一平台的产物。Kotlin + Jetpack Compose 负责电视与手机的深度体验,Next.js 负责浏览器的广度,云函数负责把碎片粘成整体——三者在一个仓库里协同演进,这正是它最值得一读的地方。
【免费下载链接】ARVIO
ARVIO - A media hub application with a modern, beautiful interface.
相关推荐
StreamVault-IPTV架构深度解析:Kotlin+Jetpack Compose+Media3多模块设计如何构建TV优先的IPTV应用
StreamVault IPTV架构深度解析:Kotlin+Jetpack Compose+Media3多模块设计如何构建TV优先的IPTV应用 StreamV
Skill Compose架构深度剖析:FastAPI+Next.js+PostgreSQL如何构建开源Agent运行时
Skill Compose架构深度剖析:FastAPI+Next.js+PostgreSQL如何构建开源Agent运行时 Skill Compose 是一个开源
PalmClaw架构深度剖析:端侧Agent Loop是如何工作的(Kotlin + Jetpack Compose实现)
PalmClaw架构深度剖析:端侧Agent Loop是如何工作的(Kotlin + Jetpack Compose实现) PalmClaw 是一个原生运行在
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考