当前 LocalMusic.ets 已演变为内容展示、播放控制、底部播放条、全屏播放页、卡片联动混杂在一起的大文件,单文件规模超过两万行,继续在原文件上实现音乐卡片和播放器能力会持续放大耦合风险。
仓库内虽然已有 LocalMusic2.ets,但它目前本质上仍是 LocalMusic 的复制体,尚未形成真正可维护的新架构。
本次设计目标是在 不修改 LocalMusic 的前提下,以 LocalMusic2 为新入口,完成播放器职责拆分,为音乐卡片、底部播放条和独立播放页提供清晰边界。
NewIndex 挂载底部播放条和全屏播放浮层,成为播放器宿主。LocalMusic2 只负责音乐分类与列表展示,不再承担播放器 UI 宿主职责。LocalMusic / LocalMusic2 已验证过的交互能力。AppStorage 依赖,允许首版保留必要兼容镜像。NewIndex.ets 负责:
isShowPlay 这类纯 UI 显示状态。OPEN_PLAYER 动作。NewIndex 不再承担具体播放逻辑,也不直接维护播放队列。
LocalMusic2.ets 负责:
LocalMusic2 不再负责:
isShowPlay 的宿主级管理。新增 MusicPlayerBuilder.ets,负责:
该文件不作为状态源头,只做播放器 UI 呈现层。
新增 MusicPlaybackController.ets,负责:
控制器是唯一播放状态源,避免多个页面各自维护一份播放器状态。
统一播放入口模型至少包含:
sourceType:来源类型,例如本地、歌单、WebDAV、Navidrome、发现页。playlistId:来源队列标识。playlistName:当前队列展示名称。songs:已拿到的歌曲对象列表。songFilePaths:只拿到路径时的回填列表。startIndex:起播索引。playType:请求时希望应用的播放模式。openPlayer:是否自动展开全屏播放页。统一状态快照至少包含:
所有页面统一走以下链路:
LocalMusic2、歌单页、WebDAV 页面、发现页等组装 PlaybackRequest。MusicPlaybackController.play(request)。request.openPlayer === true,控制器通知宿主展开全屏播放页。这样页面层不再直接调用 setShowPlayTrue()、doPlay()、startPlayOrResumePlay() 等底层方法组合。
NewIndex 负责以下 UI 宿主逻辑:
isShowPlay = true。isShowPlay = false。现有 dismissPlayerView 事件仍可保留作为过渡期兼容,但最终应由宿主层统一管理,不再让内容页充当播放器宿主。
首版采用“双轨同步”:
MusicPlaybackController 内部状态是主状态。AppStorage,保持现有组件兼容。首版保留的兼容字段包括:
currentSongprogressValueCONTROL_PlayStatuscover后续稳定后再逐步收紧 AppStorage 依赖。
EntryAbility.ets 中的卡片消息入口继续保留:
PLAY_OR_PAUSEPLAY_PREVIOUSPLAY_NEXTOPEN_PLAYERPLAY_OR_PAUSE、PLAY_PREVIOUS、PLAY_NEXT 交给 MusicPlaybackController 执行。OPEN_PLAYER 交给 NewIndex 宿主处理,直接展开全屏播放浮层。每次以下状态变化后,由 MusicPlaybackController 负责更新:
更新流程为:
PlaybackRequest、PlaybackState、MusicPlaybackController。LocalMusic2 中的大播放页 Builder 迁移到 MusicPlayerBuilder.ets。NewIndex 挂载全屏浮层。MiniPlayerBar.ets。NewIndex 统一挂载普通模式和 HiCar 模式播放条。LocalMusic2 中播放器宿主职责。isShowPlay 的直接控制。PlaybackRequest 中只有路径列表时,控制器负责回填缺失歌曲对象;回填失败的项目跳过并记录日志。MusicCardFormManager 行为,记录日志并移除失效 formId。首版以手工回归为主,必须覆盖:
如果本轮新增可稳定编写的 Hypium 用例,可优先覆盖控制器层的纯逻辑部分,例如:
PlaybackRequest 队列构建。AppStorage、@Consume、eventHub、控制器新状态源并存的过渡期会增加短期复杂度。本次重构采用“NewIndex 做宿主、LocalMusic2 做内容页、MusicPlayerBuilder 做播放页、MusicPlaybackController 做唯一控制中台”的拆法。
这是在不修改 LocalMusic 的约束下,兼顾现有交互复用、多来源兼容、音乐卡片接入和后续可维护性的最稳方案。后续实施时应严格按照迁移顺序推进,避免再次把播放器能力回流到内容页中。