CoverArt is an Android display client for the Roon ecosystem. It is designed for always-on screens and TV-class devices, showing current album art in full screen and switching to an art wall when playback is idle.
- Shows now playing title, artist, album, and high-resolution cover art from Roon Core.
- Keeps a clean visual mode by hiding normal status text; only actionable warnings are shown as overlay.
- Automatically enters a 15-cover Art Wall when playback stops, then returns to single-cover mode when music resumes.
- Supports both physical media keys and touch gestures for playback control.
- Uses local cache and color-adaptive background/text styling for stable long-running display behavior.
- Portrait now-playing uses a poster-style composition with a cover-first layout, bottom metadata band, and a conservative
Balanced/Airycover profile switch for sparse bright artwork.
- Touch gestures:
- Swipe left: next track
- Swipe right: previous track
- Swipe up: pause
- Swipe down: play
- Media keys:
- Play/Pause key multi-click: single=toggle, double=next, triple=previous
- Media Next / Previous / Play / Pause / Stop supported
- Silent volume up/down and mute handling
- Android 8.0 (API 26) or newer
- Roon Core on the same LAN
- Extension API enabled in Roon
- Stable Wi-Fi network
- Open in Android Studio and run debug build, or use CLI:
./gradlew assembleDebug - Release APK (v2.3.6) is published as
CoverArt-2.3.6-debug.apk; local debug builds are generated atapp/build/outputs/apk/debug/app-debug.apk - Install the APK to your Android device.
- Ensure device and Roon Core are in the same LAN.
- Open Roon desktop app.
- Go to
Settings > Extensions. - Find
CoverArt_Androidand enable it. - Select or confirm playback zone if needed.
- Launch CoverArt.
- Wait for auto-discovery and auto-pairing.
- During playback, the app shows single-cover now playing view.
- When playback is idle/stopped, the app transitions to Art Wall automatically.
- Use touch gestures or media keys to control playback directly from the display device.
See CHANGELOG.md for release history.
- 2.3.6 (Latest)
- Bound current album-art requests to the active playback identity so stale image responses cannot overwrite the current track display
- Added
trackId + imageKeyvalidation for current album-art responses - Synchronized transition metadata binding with internal playback state
- Added JVM regression coverage for current album-art response guarding
- 2.33
- Migrated metadata text policy decisions to a
TrackTextMeasurerabstraction backed by AndroidStaticLayout - Added balanced line breaking and safe second-pass shrink-wrap for tighter portrait metadata width
- Extracted cover, portrait profile, and Art Wall layout policies into explicit
ui/layoutresolvers with JVM coverage - Cleaned up completed maintenance docs and archived historical plans
- Migrated metadata text policy decisions to a
- 2.32
- Added explicit timeout cleanup for image requests so stale cover/preview fetches cannot block later retries
- Serialized WebSocket frame writes through a dedicated outbound writer to avoid concurrent writes interleaving on the socket
- Made message processor shutdown non-blocking during Activity teardown to reduce ANR risk
- Added regression coverage for image request lifecycle, WebSocket outbound writes, message processor cleanup, and subscription lifecycle handling
- 2.31
- Refined portrait now-playing into a poster-style layout for 9:16 displays, with a bottom-aligned metadata band, left-aligned hierarchy, and warmer text tones for long-distance readability
- Added conservative
PortraitCoverProfilerouting plusCoverCompositionAnalyzerheuristics so bright sparse covers can opt into anAiryportrait treatment without affecting landscape mode - Simplified metadata text rendering in
TrackTextSceneViewto a single-pass draw path, removing the shadow/fake-bold edge halo that could read like an outline on low-PPI framed displays - Added JVM regression coverage for cover composition classification while keeping existing metadata layout policy tests green
- 2.30
- Replaced metadata
TextViewrendering with a measured scene pipeline built fromTrackTextLayoutPolicy,AndroidTrackTextLayoutEngine, andTrackTextSceneView - Rebuilt portrait and landscape metadata layout around a cover-first
LayoutSpecwith short-edge-driven spacing and readability baselines - Added
contentWidthPxshrink-wrap and transition-time width freezing so short titles can breathe without horizontal jitter during skips - Routed metadata transitions through scene interpolation and aligned timing, stagger, and shift tokens to remove mid-animation text mutation
- Migrated metadata colors to explicit
TrackTextPaletteownership and isolatedstatusTextoverlay coloring from album-art palette updates - Added JVM regression coverage for layout policy sizing, mixed-language and low-density readability, and scene transition state handoff
- Replaced metadata
- 2.29
- Hardened WebSocket, subscription registry, and connection-monitor lifecycle handling to reduce race conditions and leaks
- Simplified message processing into a single-threaded execution path for more predictable MOO handling
- Extracted MOO dispatch, image response processing, palette handling, and queue coordination into dedicated collaborators
- Added parser/input hardening for oversized
Content-Lengthand IPv6 host parsing - Expanded regression coverage for routing, parser limits, subscription removal, and connection-input parsing
- 2.28
- Optimized Art Wall loading path: moved bitmap decoding off the main thread to reduce UI stutter
- Improved idle/playback switching stability by replacing delayed Timer switching with main-thread scheduling
- Added Art Wall snapshot/restore on rotation and size-aware bitmap caching for faster orientation changes
- Refactored cover display / art wall / layout responsibilities into dedicated managers for maintainability
- Added unit tests for Art Wall rotation pool logic
- 2.26
- Improved first-pairing authorization hint reliability when registration responses are delayed or missing
- Added fallback handling for empty registration responses to always surface Roon-side authorization guidance
- Hardened register response correlation to avoid missing pairing-state transitions
- Prevented bottom system-gesture area from triggering swipe-up pause when exiting app
- 2.25
- Premium UI Refactoring: Extracted dimensions into centralized
UIDesignTokens - Adaptive Static Typography: Replaced marquee effects with intelligent multi-line layout and kerning for perfect immersion
- Art Wall Rebirth: Replaced rigid 3D card flips with elegant cross-fade "breathing" transitions and soft elevations
- Premium UI Refactoring: Extracted dimensions into centralized
- 2.24
- Improved track transition aesthetics with physics-based spring animations
- Added cascade text animation and Z-axis drop effect for cover art
- Perfected audio-visual synchronization by strictly aligning with
playingstate - Added async image rendezvous handling for slow networks
- Improved art wall idle detection and timeout suppression
- 2.23
- Added touch gesture playback controls (left/right/up/down swipes)
- Added track transition animation feedback when changing tracks
- Kept clean status overlay policy and existing keyboard/media-key control path
- 2.21
- Switched user-facing UI status text to English
- Added alert-only status overlay visibility strategy
- Improved first-pairing authorization hint behavior
CoverArt 是面向 Roon 生态的 Android 展示端应用。 它面向常亮大屏/电视类设备,主界面专注展示当前播放专辑封面,播放停止时自动进入艺术墙模式。
- 实时展示 Roon 当前播放信息:歌曲名、艺术家、专辑名、高清封面。
- 状态提示采用“告警优先”策略:正常播放时保持画面干净,仅在需要处理的问题场景显示提示层。
- 播放停止后自动进入 15 宫格艺术墙;恢复播放后自动回到单封面模式。
- 同时支持物理媒体键与触摸手势控制播放。
- 本地缓存与主色调自适应背景/文字,提升长期运行稳定性与观感一致性。
- 竖屏播放态采用更接近画框海报的 cover-first 构图,底部信息带左对齐,并通过保守的
Balanced/Airy封面分流适配高亮度、大留白封面。
- 触摸手势:
- 左滑:下一曲
- 右滑:上一曲
- 上滑:暂停
- 下滑:开始播放
- 物理媒体键:
- 播放键多击:单击=播放/暂停,双击=下一曲,三击=上一曲
- 支持 Next / Previous / Play / Pause / Stop
- 支持静默音量增减与静音
- Android 8.0(API 26)及以上
- 与 Roon Core 在同一局域网
- 已在 Roon 中启用 Extension API
- 网络连接稳定
- 使用 Android Studio 打开工程并运行,或命令行执行:
./gradlew assembleDebug - Release APK(v2.3.6)发布为
CoverArt-2.3.6-debug.apk;本地 debug 构建产物位于app/build/outputs/apk/debug/app-debug.apk - 安装生成的 APK 到 Android 设备。
- 确保设备与 Roon Core 在同一局域网。
- 打开 Roon 桌面端。
- 进入
设置 > 扩展。 - 找到
CoverArt_Android并启用。 - 如有需要,在扩展设置中确认播放区域(Zone)。
- 启动 CoverArt。
- 等待自动发现/自动配对。
- 播放中显示单封面 Now Playing。
- 停播后自动切换为艺术墙。
- 可直接在屏幕上滑动控制播放,或使用媒体键操作。
完整版本记录见 CHANGELOG.md。
- 2.3.6(最新)
- 将当前封面请求绑定到正在播放的曲目身份,避免陈旧图片响应覆盖当前曲目展示
- 为当前封面响应增加
trackId + imageKey校验 - 让转场 metadata 绑定同步写回内部播放状态
- 补充当前封面响应 guard 的 JVM 回归测试
- 2.33
- 将 metadata 文本策略判断迁移到
TrackTextMeasurer抽象,并由 AndroidStaticLayout提供真实测量 - 增加 balanced line breaking 与安全二段式 shrink-wrap,让竖屏 metadata 宽度更贴合内容
- 将封面、竖屏 profile 和 Art Wall 布局策略提取到明确的
ui/layoutresolver,并补充 JVM 覆盖 - 清理已完成维护文档,并归档历史计划
- 将 metadata 文本策略判断迁移到
- 2.32
- 为图片请求增加显式超时清理,避免陈旧封面/预览请求阻塞后续重试
- 通过独立出站 writer 串行化 WebSocket frame 写入,避免多线程并发写同一 socket 时帧内容交错
- Activity 销毁时改为非阻塞关闭消息处理器,降低生命周期回调触发 ANR 的风险
- 补充图片请求生命周期、WebSocket 出站写入、消息处理器清理与订阅生命周期相关回归测试
- 2.31
- 将竖屏 Now Playing 收敛为更适合 9:16 画屏的海报式布局:封面优先、底部信息带贴底、文字层级左对齐,并统一为偏暖文字色提升远看可读性
- 新增保守的
PortraitCoverProfile分流与CoverCompositionAnalyzer轻量封面分析,让高亮度、大留白封面进入Airy竖屏样式,同时不影响横屏布局 TrackTextSceneView改为单层文字绘制,移除阴影叠画和标题 fake bold,降低低 PPI 画屏上容易被看成“文字有边框”的暗边感- 补充封面分类相关 JVM 回归测试,并保持现有 metadata 布局策略测试通过
- 2.30
- 用
TrackTextLayoutPolicy、AndroidTrackTextLayoutEngine和TrackTextSceneView组成新的测量式 scene 文本渲染链路,替换元数据TextView直绘 - 围绕 cover-first
LayoutSpec重写横竖屏元数据布局,采用短边驱动的间距与远距离可读性基线 - 新增
contentWidthPx基础 shrink-wrap,并在转场期间冻结 metadata 容器宽度,避免切歌时横向抖动 - 文本转场改为 scene 插值驱动,并统一时长、级联延迟与位移 token,移除动画中途直接改文案
- 元数据配色迁移为显式
TrackTextPalette,同时把statusTextoverlay 颜色所有权从专辑主色联动里剥离 - 补充布局策略、低密度大屏/中英文混排可读性,以及 scene 转场状态衔接的 JVM 回归测试
- 用
- 2.29
- 强化 WebSocket、订阅注册表与连接监控生命周期处理,降低竞态与资源泄漏风险
- 将消息处理链路收敛为单线程串行执行,提升 MOO 协议处理可预测性
- 拆出 MOO 路由、图片响应处理、主色调管理、队列协调等独立协作类,降低
MainActivity复杂度 - 增强协议与输入健壮性,补上超大
Content-Length限制与 IPv6 地址解析 - 补充路由、解析上限、订阅移除和连接输入解析相关回归测试
- 2.28
- 优化艺术墙图片加载链路:Bitmap 解码移出主线程,降低卡顿
- 优化停播/恢复切换稳定性:延迟切换改为主线程调度,降低竞态风险
- 新增横竖屏切换时的艺术墙快照恢复与尺寸感知缓存,加快旋转恢复速度
- 拆分封面显示 / 艺术墙 / 布局编排职责,提升代码可维护性
- 新增艺术墙轮换池逻辑单元测试,增强回归保护
- 2.26
- 优化首次配对授权提示可靠性,覆盖注册响应延迟/丢失场景
- 新增注册空响应兜底处理,确保能提示去 Roon 侧完成授权
- 强化 register 响应关联,降低配对状态丢失风险
- 修复底部系统手势区域误触发“上滑暂停”,避免退出应用时误暂停播放
- 2.25
- 高级视觉重构 (Premium UI):引入
UIDesignTokens标准化设计语言,剥离硬编码约束 - 沉静式排版:全面消除跑马灯,引入自适应折行、文字安全边距与画廊级字间距
- 艺术墙 (Art Wall) 原生质感:移除生硬的 3D 翻转卡片与 2px 勾边,重制为极具呼吸感的平滑交叉渐变 (Cross-fade) 与弥散阴影
- 高级视觉重构 (Premium UI):引入
- 2.24
- 提升切歌动效手感,引入物理弹簧动画 (SpringAnimation)
- 增加文字错落浮现与封面 Z 轴沉缩呼吸效果
- 极其精准的音画同步机制,严格对齐
playing状态 - 新增异步超清图片加载过程的平滑遮罩处理
- 优化弱网及缓冲时的艺术墙防切误判
- 2.23
- 新增触摸手势播放控制(左/右/上/下滑)
- 新增切歌动画反馈
- 保留并兼容原有媒体键控制与状态提示策略
- 2.21
- UI 状态文案统一英文
- 增加仅告警可见的状态提示层策略
- 优化首次配对授权提示逻辑
- Issue / PR: GitHub