跳转到内容

18. Spotify 音乐流媒体

V1 — 1个用户:浏览器音乐播放器

Section titled “V1 — 1个用户:浏览器音乐播放器”

你想做一个个人音乐播放器网页,播放本地或在线音频文件,管理自己的播放列表。

用纯前端实现HTML5 Audio播放器,播放列表存localStorage。

帮我用纯HTML+CSS+JavaScript实现一个Web音乐播放器:
1. 播放器核心(HTML5 Audio API):
- 播放/暂停、上一首/下一首
- 进度条:可点击跳转,显示当前时间/总时长
- 音量控制:滑块调节+静音按钮
- 播放模式:顺序播放、随机播放、单曲循环
2. 播放列表:
- 预设10首歌(用免费音频URL,如freemusicarchive.org)
- 每首歌:title, artist, album, duration, url, cover_url
- 当前播放歌曲高亮
- 拖拽排序(Drag & Drop API)
3. 自定义歌单:
- 创建歌单、重命名、删除
- 把歌曲添加到歌单/从歌单移除
- 切换不同歌单
4. UI设计:
- 底部固定播放栏(类Spotify)
- 左侧歌单列表
- 右侧歌曲列表
- 专辑封面旋转动画(播放时)
5. 持久化:播放列表、歌单、当前播放进度存localStorage
6. 键盘快捷键:空格=播放暂停,←→=切歌,↑↓=音量
纯原生JS,CSS布局模仿Spotify风格(暗色主题)。
  • 音频正常播放,进度条同步
  • 切歌、随机播放、单曲循环正确
  • 拖拽排序播放列表
  • 自定义歌单CRUD正常
  • 刷新后恢复到上次播放位置
  • HTML5 Audio API → Module: 浏览器多媒体API
  • Drag & Drop API → Module: 浏览器原生拖拽
  • CSS暗色主题和布局 → Module: CSS主题设计
  • 媒体播放状态管理 → Module: 状态管理

V2 — 10个用户:音乐上传和搜索

Section titled “V2 — 10个用户:音乐上传和搜索”

10个朋友想一起分享音乐,需要后端支持音乐上传、元数据管理和搜索。

Go后端实现音乐文件上传、元数据存储、搜索和流式播放。

帮我用Go+Gin+SQLite实现音乐后端服务:
1. 数据模型:
- artists: id, name
- albums: id, title, artist_id, cover_url, release_year
- tracks: id, title, artist_id, album_id, duration, file_path, file_size, created_at
- playlists: id, name, user_id, created_at
- playlist_tracks: playlist_id, track_id, position
2. 音乐上传:
- POST /api/tracks/upload — multipart上传音频文件+元数据
- 支持格式:mp3, flac, wav, ogg
- 限制:单文件最大50MB
- 文件存本地 data/music/ 目录
- 用Go库读取音频元数据(ID3 tag)自动填充artist/album
3. 搜索:
- GET /api/search?q=xxx — 搜索歌曲、歌手、专辑
- SQLite LIKE模糊匹配(小规模够用)
- 返回分类结果:tracks[], artists[], albums[]
4. 播放:
- GET /api/tracks/:id/stream — 返回音频文件
- 设置正确的Content-Type和Content-Length
- 支持Accept-Ranges(稍后V3扩展)
5. 歌单API:
- CRUD歌单
- 添加/移除歌曲到歌单
- 调整歌曲顺序(position字段)
6. 浏览:
- GET /api/albums — 专辑列表
- GET /api/albums/:id/tracks — 专辑内歌曲
- GET /api/artists/:id — 歌手详情+专辑列表
SQLite单文件存储,不需要额外服务。
  • 音乐文件上传成功并能播放
  • ID3 tag自动提取填充元数据
  • 搜索能找到歌曲名、歌手名
  • 歌单增删改查正常
  • 不支持的文件格式被拒绝
  • 音频文件处理和ID3元数据 → Module: 多媒体处理
  • 文件上传和Content-Type处理 → Module: HTTP文件处理
  • 多表关联的数据建模 → Module: 关系型建模

V3 — 100个用户:流式播放和生产化

Section titled “V3 — 100个用户:流式播放和生产化”

用户反馈:大文件加载慢,拖动进度条要重新下载整首歌。需要支持HTTP Range请求实现真正的流式播放。

实现HTTP Range分段请求、PostgreSQL存储元数据、歌单协作功能。

在V2基础上实现流式播放和生产化:
1. HTTP Range流式播放:
- 处理Range请求头:Range: bytes=0-1048575
- 返回206 Partial Content + Content-Range头
- 支持多段Range(可选)
- 这样拖动进度条只下载需要的部分
2. 存储升级:SQLite → PostgreSQL
3. 歌单增强:
- 歌单封面:取前4首歌的专辑封面拼成2x2网格
- 协作歌单:多个用户可编辑同一歌单
- collaborators表:playlist_id, user_id, role(owner/editor/viewer)
- 歌单分享:生成分享链接
4. 播放历史:
- play_history表:user_id, track_id, played_at, duration_listened
- GET /api/history — 最近播放列表
- 统计:最常听的歌曲/歌手(本周/本月)
5. 收藏库:
- POST /api/library/tracks/:id — 收藏歌曲
- POST /api/library/albums/:id — 收藏专辑
- GET /api/library — 我的收藏库
6. 音频转码(可选):
- 上传时统一转为320kbps MP3
- 用ffmpeg命令行调用
提供docker-compose.yml包含PostgreSQL。
  • 拖动进度条不重新下载整首歌
  • 返回正确的206状态码和Content-Range头
  • 协作歌单多人可编辑
  • 播放历史正确记录
  • 最常听统计数据准确
  • HTTP Range请求和206 Partial Content → Module: HTTP协议进阶
  • 协作权限模型(RBAC) → Module: 权限设计
  • 播放历史和用户行为记录 → Module: 用户行为分析
  • ffmpeg音频处理 → Module: 多媒体转码

V4 — 1000个用户:离线缓存和播放队列

Section titled “V4 — 1000个用户:离线缓存和播放队列”

用户在通勤时网络不好,想离线听歌。同时播放队列需要更智能:插队播放、稍后播放。

Service Worker缓存已播放歌曲实现离线播放,智能播放队列管理。

在V3基础上实现离线缓存和智能队列:
1. Service Worker离线缓存:
- 注册Service Worker拦截音频请求
- 策略:播放过的歌曲自动缓存到Cache Storage
- 缓存容量限制:最多500MB,LRU淘汰最久未听的
- 离线时从缓存播放,有网络时优先网络
- 显示已缓存的歌曲列表和占用空间
2. 主动下载:
- "下载"按钮:主动缓存歌曲/歌单供离线播放
- 下载进度显示
- 批量下载整个歌单
3. 智能播放队列:
- 当前队列:正在播放+即将播放列表
- 插队播放:把一首歌插到下一首位置
- 稍后播放:加到队列末尾
- 从队列移除
- 拖拽调整队列顺序
4. 队列持久化:
- 播放队列存localStorage
- 关闭浏览器后再打开,恢复队列和播放位置
5. 淡入淡出(Crossfade):
- 当前歌曲结束前3秒开始淡出
- 下一首歌同时淡入
- 用Web Audio API实现音量渐变
6. 歌词显示(可选):
- LRC格式歌词解析
- 逐行高亮同步
重点实现Service Worker缓存策略和播放队列管理。
  • 播放过的歌曲断网后仍可播放
  • 缓存超过500MB时自动淘汰
  • 插队播放/稍后播放正确排列
  • 拖拽调整队列顺序
  • Crossfade切歌平滑过渡
  • Service Worker和Cache API → Module: PWA技术
  • LRU缓存淘汰策略 → Module: 缓存算法
  • Web Audio API音频处理 → Module: Web Audio
  • 播放队列数据结构(双端队列) → Module: 数据结构应用

用户听完歌单不知道听什么。需要根据听歌历史推荐相似音乐,自动生成播放队列。

基于听歌历史的协同过滤推荐,自动生成个性化电台。

在V4基础上实现推荐和电台功能:
1. 协同过滤推荐:
- 基于物品的协同过滤(Item-based CF):
- 计算歌曲之间的相似度(共同听过这两首歌的用户比例)
- 离线计算:每天更新歌曲相似度矩阵
- 存入Redis: similar_tracks:{track_id} → [{track_id, score}, ...]
- 推荐逻辑:用户最近听的歌 → 找到相似歌曲 → 过滤已听 → 排序
2. 个性化电台:
- POST /api/radio/start — 基于一首歌/歌手/风格创建电台
- GET /api/radio/next — 获取下一首推荐歌曲
- 电台逻辑:
- 种子歌曲 → 找相似 → 加入一些探索性(20%随机)
- 不重复最近50首已播放
- 每次返回1首,播放完再请求
3. 每日推荐(Daily Mix):
- 分析用户听歌风格聚类
- 生成3个Daily Mix歌单,每个侧重一种风格
- 每天凌晨重新生成
- GET /api/recommendations/daily — 获取今日推荐
4. 发现周报(Discover Weekly):
- 每周一生成30首推荐歌曲
- 重点推荐用户没听过但可能喜欢的
- 结合协同过滤 + 热门歌曲
5. 用户口味画像:
- 统计维度:最爱风格、最爱歌手、听歌时段、活跃度
- GET /api/profile/taste — 口味画像数据
- 前端可视化(雷达图)
重点实现Item-based CF算法和电台的种子扩展逻辑。
  • 歌曲相似度计算合理
  • 电台播放不重复且风格连贯
  • Daily Mix覆盖用户主要听歌风格
  • 推荐中包含用户未听过的歌曲
  • 口味画像数据准确
  • Item-based协同过滤 → Module: 推荐算法
  • 电台模式的种子扩展算法 → Module: 音乐推荐
  • 用户画像构建 → Module: 用户建模
  • 探索与利用(Exploration vs Exploitation) → Module: 推荐策略

V6 — 10万+用户:多端同步和多码率

Section titled “V6 — 10万+用户:多端同步和多码率”

用户在手机上听到一半,想在电脑上继续(类Spotify Connect)。不同网络环境需要不同音质。

WebSocket实现多端播放状态同步,多码率自适应流式播放。

设计并实现多端同步和自适应流媒体:
1. 多端同步(Spotify Connect模式):
- 概念:一个用户多个设备,任何设备可控制任何设备的播放
- WebSocket连接:所有设备连接到 /ws/player
- 同步状态:{current_track, position, is_playing, volume, queue}
- 设备列表:GET /api/devices — 当前在线设备列表
- 切换设备:POST /api/player/transfer — 把播放转移到另一台设备
2. 同步协议:
- 设备每5秒上报播放位置
- 控制命令:play, pause, seek, next, previous, volume
- 一台设备操作 → 服务器广播给该用户所有设备
- 冲突处理:最后操作的设备优先
3. 多码率编码:
- 上传时转码为多个码率:
- 低质量:96kbps AAC(省流量)
- 标准:160kbps AAC
- 高质量:320kbps MP3
- 无损:FLAC(可选,VIP用户)
- tracks表增加字段:各码率文件路径和大小
4. 自适应码率选择:
- 前端检测网络速度(Navigation Timing API)
- 根据网络状况自动切换码率
- WiFi默认高质量,4G默认标准,弱网低质量
- 用户可手动覆盖设置
5. 播放统计和版税计算:
- 播放>30秒计为一次有效播放
- 统计表:track_id, play_count, total_duration
- 版税分配逻辑:每月总收入按播放次数比例分给创作者
- GET /api/artists/:id/stats — 创作者数据面板
6. 社交功能:
- 好友动态:xxx正在听《xxx》
- 分享歌曲/歌单到外部平台(生成分享卡片)
重点实现WebSocket多端同步协议和自适应码率选择逻辑。
  • 两个标签页同步播放状态
  • 在一个设备暂停,另一个设备同步暂停
  • 切换设备后播放位置无缝衔接
  • 网络变差时自动降低码率
  • 播放>30秒正确计为有效播放
  • 多设备状态同步协议设计 → Module: 实时同步
  • 自适应码率(ABR)的策略 → Module: 流媒体技术
  • WebSocket在音乐场景的应用 → Module: WebSocket实战
  • 版税分配的技术实现 → Module: 计费系统
  • 音频转码管线(ffmpeg) → Module: 多媒体工程