音频播放器.md 16 KB

音频播放器

本文引用的文件

  • audio.ts
  • index.vue
  • detail.vue
  • index.vue
  • MiniPlayer.vue
  • index.ts
  • player.controller.ts
  • player.service.ts
  • history.controller.ts
  • history-batch.controller.ts
  • app.ts
  • DEPLOY.md

目录

  1. 简介
  2. 项目结构
  3. 核心组件
  4. 架构总览
  5. 详细组件分析
  6. 依赖关系分析
  7. 性能考虑
  8. 故障排查指南
  9. 结论
  10. 附录

简介

本文件面向“音频播放器”功能,系统性梳理前端播放器组件设计、状态管理、与后端服务的交互机制,以及播放控制、播放列表管理、状态同步与持久化、性能优化与集成 API。目标是帮助开发者快速理解并扩展播放器能力,覆盖播放/暂停、进度拖拽、倍速播放、循环播放、章节导航、历史记录、断点续播等关键特性。

项目结构

播放器相关的核心代码分布在前端 uni-app 项目与后端 Koa 服务之间:

  • 前端
    • 播放器页面:负责 UI、交互与状态展示
    • 播放器状态仓库:集中管理播放状态、播放列表、播放模式与速率
    • 组件:迷你播放器、下载组件等
    • 类型定义:统一的音频项与响应结构
  • 后端

    • 播放器模块:进度记录、最近播放、章节合并等
    • 历史模块:音频生成历史与批量删除
    • 应用入口:注册路由与静态资源服务

      graph TB
      subgraph "前端 uni-app"
      P["播放器页面<br/>pages/player/index.vue"]
      S["播放器状态仓库<br/>store/audio.ts"]
      M["迷你播放器<br/>components/MiniPlayer.vue"]
      T["类型定义<br/>types/index.ts"]
      end
      subgraph "后端 Koa"
      PC["播放器控制器<br/>modules/player/player.controller.ts"]
      PS["播放器服务<br/>modules/player/player.service.ts"]
      HC["历史控制器<br/>modules/history/history.controller.ts"]
      HBC["历史批量控制器<br/>modules/history/history-batch.controller.ts"]
      APP["应用入口<br/>app.ts"]
      end
      P --> |"调用/读取"| S
      P --> |"调用"| PC
      S --> |"调用"| PS
      P --> |"读取"| T
      M --> |"读取"| S
      PC --> |"读取/写入"| PS
      HC --> |"读取/写入"| PS
      HBC --> |"读取/写入"| PS
      APP --> |"注册路由"| PC
      APP --> |"注册路由"| HC
      APP --> |"注册路由"| HBC
      

图表来源

  • index.vue
  • audio.ts
  • MiniPlayer.vue
  • index.ts
  • player.controller.ts
  • player.service.ts
  • history.controller.ts
  • history-batch.controller.ts
  • app.ts

章节来源

  • index.vue
  • audio.ts
  • MiniPlayer.vue
  • index.ts
  • player.controller.ts
  • player.service.ts
  • history.controller.ts
  • history-batch.controller.ts
  • app.ts

核心组件

  • 播放器状态仓库(Pinia)
    • 负责音频上下文生命周期、播放状态、播放列表、播放模式、播放速率、当前时间与总时长
    • 提供播放/暂停、上一首/下一首、跳转、倍速、设置列表等方法
  • 播放器页面(Vue 组件)
    • 负责 UI 展示、事件绑定、歌词同步、播放列表展示、睡眠定时、收藏与分享
    • 从后端拉取播放列表与章节信息,驱动状态仓库
  • 后端播放器模块
    • 提供播放进度记录、更新、删除、最近播放列表等接口
    • 提供章节音频列表与详情接口,支持章节合并(章级自动合并小节音频)

章节来源

  • audio.ts
  • index.vue
  • player.controller.ts
  • player.service.ts

架构总览

播放器采用“前端状态仓库 + 后端播放器服务”的分层架构:

  • 前端通过状态仓库统一调度播放行为,页面组件仅负责渲染与交互
  • 后端提供播放进度与最近播放等持久化能力,以及章节音频聚合能力
  • 应用入口统一注册路由,静态资源服务暴露上传目录

    sequenceDiagram
    participant UI as "播放器页面"
    participant Store as "状态仓库"
    participant Ctrl as "播放器控制器"
    participant Svc as "播放器服务"
    participant DB as "数据库"
    UI->>Store : "播放/暂停/跳转/倍速/列表设置"
    Store->>Ctrl : "保存/查询播放进度"
    Ctrl->>Svc : "savePlayProgress/getPlayProgress"
    Svc->>DB : "upsert/update/findMany"
    DB-->>Svc : "记录"
    Svc-->>Ctrl : "记录"
    Ctrl-->>Store : "响应"
    Store-->>UI : "状态更新"
    

图表来源

  • index.vue
  • audio.ts
  • player.controller.ts
  • player.service.ts

详细组件分析

前端播放器组件设计

  • 状态与计算属性
    • 播放状态:播放/暂停、当前时间、总时长、播放速率、播放模式
    • 列表状态:当前索引、是否有上一首/下一首、播放列表是否存在
  • 事件与交互
    • 播放/暂停、上一首/下一首、进度拖拽、倍速选择、播放模式切换
    • 歌词同步:基于 LRC 或按句子估算的时间轴
    • 睡眠定时:定时暂停,支持“当前播放结束”模式
    • 收藏与分享:调用后端接口与平台能力
  • 列表与章节

    • 从专辑章节列表构建播放列表,支持章节导航
    • 若无专辑信息,回退到通用播放列表

      flowchart TD
      Start(["进入播放页"]) --> LoadAudio["获取音频详情"]
      LoadAudio --> HasURL{"有音频URL?"}
      HasURL --> |否| Empty["提示未生成音频"]
      HasURL --> |是| FetchList["获取播放列表"]
      FetchList --> BuildList["构建章节播放列表"]
      BuildList --> Lyrics["解析/生成歌词时间轴"]
      Lyrics --> Play["初始化音频上下文并播放"]
      Play --> UI["渲染UI与交互"]
      UI --> Controls{"用户操作"}
      Controls --> |播放/暂停| Toggle["切换播放状态"]
      Controls --> |进度拖拽| Seek["seek() 更新时间"]
      Controls --> |倍速| Rate["setPlayRate()"]
      Controls --> |模式| Mode["togglePlayMode()"]
      Controls --> |收藏/分享| Fav["PUT /audio/:id/favorite / 分享"]
      Controls --> |下一首| Next["playNext()"]
      Controls --> |上一首| Prev["playPrev()"]
      Controls --> |睡眠定时| Sleep["定时暂停"]
      Toggle --> UI
      Seek --> UI
      Rate --> UI
      Mode --> UI
      Fav --> UI
      Next --> UI
      Prev --> UI
      Sleep --> UI
      

图表来源

  • index.vue
  • audio.ts

章节来源

  • index.vue
  • audio.ts

播放控制功能

  • 播放/暂停
    • 通过状态仓库的切换方法控制音频上下文
  • 进度拖拽
    • slider change 事件触发 seek,更新当前时间
  • 倍速播放
    • 倍速选择器设置 playbackRate
  • 循环播放

    • 顺序/列表循环/单曲循环/随机播放模式切换与处理逻辑

      sequenceDiagram
      participant Page as "播放器页面"
      participant Store as "状态仓库"
      participant Ctx as "音频上下文"
      Page->>Store : "togglePlay()"
      alt 当前播放
      Store->>Ctx : "pause()"
      else 当前暂停
      Store->>Ctx : "play()"
      end
      Store-->>Page : "isPlaying 更新"
      

图表来源

  • index.vue
  • audio.ts

章节来源

  • index.vue
  • audio.ts

播放列表管理机制

  • 章节导航
    • 从专辑章节列表构建播放列表,支持章节点击播放
  • 历史记录保存
    • 通过播放器控制器保存/更新播放进度,支持按章节查询与批量删除
  • 播放顺序控制

    • 顺序、列表循环、单曲循环、随机播放四种模式

      sequenceDiagram
      participant Page as "播放器页面"
      participant Store as "状态仓库"
      participant Ctrl as "播放器控制器"
      participant Svc as "播放器服务"
      participant DB as "数据库"
      Page->>Ctrl : "POST /api/player/progress {audioId, progress, duration}"
      Ctrl->>Svc : "savePlayProgress(userId, audioId, progress, duration)"
      Svc->>DB : "upsert playRecord"
      DB-->>Svc : "记录"
      Svc-->>Ctrl : "记录"
      Ctrl-->>Page : "保存成功"
      

图表来源

  • index.vue
  • player.controller.ts
  • player.service.ts

章节来源

  • index.vue
  • detail.vue
  • index.vue
  • player.controller.ts
  • player.service.ts

播放器状态同步机制

  • 多设备状态同步
    • 通过后端播放进度接口进行跨设备同步(保存/查询)
  • 断点续播
    • 页面 onShow 时同步当前时间与总时长,保证重新进入页面后状态一致
  • 播放进度持久化

    • 前端定时上报进度,后端 upsert 存储,避免丢失

      sequenceDiagram
      participant Page as "播放器页面"
      participant Store as "状态仓库"
      participant Ctrl as "播放器控制器"
      participant Svc as "播放器服务"
      participant DB as "数据库"
      loop 播放中
      Page->>Store : "onTimeUpdate -> currentTime"
      Store->>Ctrl : "上报进度"
      Ctrl->>Svc : "updatePlayProgress(userId, audioId, progress, duration?)"
      Svc->>DB : "update playRecord"
      end
      Page->>Ctrl : "GET /api/player/recent"
      Ctrl->>Svc : "getRecentPlayRecords(userId, limit)"
      Svc->>DB : "findMany playRecord"
      DB-->>Svc : "记录列表"
      Svc-->>Ctrl : "记录列表"
      Ctrl-->>Page : "最近播放"
      

图表来源

  • index.vue
  • audio.ts
  • player.controller.ts
  • player.service.ts

章节来源

  • index.vue
  • audio.ts
  • player.controller.ts
  • player.service.ts

性能优化策略

  • 音频缓冲与元数据处理
    • 避免使用异常的音频元数据时长,仅在合理范围内更新显示时长
  • 内存管理
    • 页面卸载时不清除音频上下文,以支持后台播放;销毁方法保留以便回收
  • 网络优化
    • 静态资源通过 Nginx 暴露 /uploads,启用缓存头,减少重复下载
    • 建议引入 Redis 缓存热门接口(如播放列表、最近播放)

章节来源

  • audio.ts
  • DEPLOY.md

播放器集成 API 与使用示例

  • 获取播放进度
    • GET /api/player/progress?audioId={id}
  • 保存播放进度
    • POST /api/player/progress {audioId, progress, duration}
  • 更新播放进度
    • PUT /api/player/progress/{audioId} {progress, duration?}
  • 删除播放记录
    • DELETE /api/player/progress/{audioId}
  • 批量删除播放记录
    • DELETE /api/player/progress/batch {audioIds: number[]}
  • 获取最近播放
    • GET /api/player/recent
  • 获取章节音频详情(适配旧播放器)
    • GET /api/player/audio/:id
  • 获取章节音频列表(适配旧播放器)
    • GET /api/player/audio/list?page&pageSize
  • 更新章节公开状态
    • PUT /api/player/audio/:id/public {isPublic}

以上接口由后端控制器与服务实现,前端通过封装的请求工具调用。

章节来源

  • player.controller.ts
  • player.service.ts
  • app.ts

依赖关系分析

  • 前端依赖
    • 状态仓库依赖音频上下文(uni.createInnerAudioContext)
    • 页面依赖状态仓库与类型定义
    • 组件依赖状态仓库与工具函数
  • 后端依赖

    • 控制器依赖服务层与中间件
    • 服务层依赖数据库模型与音频合并工具
    • 应用入口统一注册路由与静态资源

      graph LR
      UI["播放器页面"] --> Store["状态仓库"]
      UI --> Types["类型定义"]
      Store --> Types
      Store --> Svc["播放器服务"]
      Svc --> DB["数据库"]
      Ctrl["播放器控制器"] --> Svc
      Ctrl --> DB
      App["应用入口"] --> Ctrl
      App --> Static["静态资源 /uploads"]
      

图表来源

  • index.vue
  • audio.ts
  • index.ts
  • player.controller.ts
  • player.service.ts
  • app.ts

章节来源

  • index.vue
  • audio.ts
  • index.ts
  • player.controller.ts
  • player.service.ts
  • app.ts

性能考虑

  • 前端
    • 合理使用 onTimeUpdate 频率,避免频繁重渲染
    • 歌词同步按需滚动,避免过度 DOM 操作
  • 后端
    • 对播放进度接口使用缓存(Redis)
    • 对列表接口分页与排序优化
    • 静态资源缓存与压缩

[本节为通用指导,无需特定文件引用]

故障排查指南

  • 播放报错
    • 检查音频 URL 是否可访问,确认后端静态资源映射正确
    • 查看音频上下文错误码与 readyState
  • 进度不同步
    • 确认前端定时上报与后端 upsert 成功
    • 检查用户身份与章节归属
  • 列表为空
    • 确认专辑章节是否存在音频 URL
    • 检查公开状态与用户权限

章节来源

  • audio.ts
  • player.controller.ts
  • player.service.ts

结论

本播放器以“前端状态仓库 + 后端播放器服务”为核心,实现了播放控制、播放列表、歌词同步、睡眠定时、收藏分享与进度持久化等关键能力。通过清晰的前后端职责划分与标准 API,具备良好的扩展性与可维护性。建议后续完善多设备状态同步、离线缓存与断点续播体验,并持续优化性能与稳定性。

[本节为总结,无需特定文件引用]

附录

  • 历史记录管理
    • 获取历史列表:GET /api/history/
    • 批量删除历史:POST /api/history/batch-delete {ids: string[]}

章节来源

  • history.controller.ts
  • history-batch.controller.ts