设计目标
在博客中嵌入音乐播放功能,核心需求:
- 独立音乐页面:全功能播放器,包含歌单切换、黑胶唱片动画、歌词
- 全局迷你挂件:右下角小播放器,切换页面不中断播放
- 跨页面状态同步:歌曲进度、播放状态在所有页面共享
技术选型
选择 APlayer 作为播放器引擎,它是一个轻量级的开源 HTML5 音乐播放器。
1<link rel="stylesheet" href="/css/APlayer.min.css">
2<script src="/js/APlayer.min.js"></script>
初始化:
1const ap = new APlayer({
2 container: document.getElementById('player'),
3 mini: false,
4 autoplay: false,
5 theme: '#f44336',
6 loop: 'all',
7 order: 'list',
8 preload: 'auto',
9 volume: 0.7,
10 mutex: true,
11 listFolded: false,
12 listMaxHeight: 250,
13 lrcType: 3,
14 audio: [
15 {
16 name: '歌名',
17 artist: '歌手',
18 url: '/music/song.mp3',
19 cover: '/images/music/cover.jpg',
20 lrc: '/music/song.lrc'
21 }
22 ]
23});
黑胶唱片旋转动画
唱片旋转是音乐页面的视觉亮点。
HTML 结构
1<div class="vinyl-container">
2 <div class="vinyl-cover"></div>
3 <div class="vinyl-disc">
4 <div class="vinyl-label"></div>
5 </div>
6 <div class="vinyl-arm"></div>
7</div>
CSS 动画
1.vinyl-disc {
2 animation: vinylSpin 3s linear infinite paused;
3}
4
5.vinyl-disc.playing {
6 animation-play-state: running;
7}
8
9@keyframes vinylSpin {
10 0% { transform: rotate(0deg); }
11 100% { transform: rotate(360deg); }
12}
播放时 animation-play-state: running,暂停时 paused,唱片旋转和唱针角度联动切换。
歌词同步
APlayer 内建 LRC 歌词解析能力。配置 lrcType: 3 并提供 LRC 文件 URL:
1[ti:歌名]
2[ar:歌手]
3[00:15.20]第一句歌词
4[00:20.50]第二句歌词
5[00:28.30]第三句歌词
歌词滚动区域自动追踪当前播放句,高亮绿色。
跨页面状态同步(关键)
全局音乐播放器的核心挑战是:用户从文章页切换到首页时,音乐不能中断。
SessionStorage 方案
APlayer 是页面级实例,页面跳转后实例被销毁,音乐中断。解决方法是:
- 将音乐挂件放在固定框架(iframe 或独立 JS 上下文)
- 或者使用更简单的方案:创建一个隐藏的 iframe 承载 APlayer,所有页面通过 postMessage 与它通信
1// 检查是否已存在全局播放器 iframe
2let playerFrame = document.getElementById('global-player-frame');
3
4if (!playerFrame) {
5 playerFrame = document.createElement('iframe');
6 playerFrame.id = 'global-player-frame';
7 playerFrame.src = '/player.html';
8 playerFrame.style.display = 'none';
9 document.body.appendChild(playerFrame);
10}
11
12function playSong(songIndex) {
13 playerFrame.contentWindow.postMessage({
14 action: 'play',
15 songIndex: songIndex
16 }, '*');
17}
迷你挂件
右下角迷你挂件显示当前歌曲名称和播放/暂停按钮:
1<div class="mini-player-widget" id="mini-player">
2 <div class="mini-cover" id="mini-cover"></div>
3 <div class="mini-info">
4 <span class="mini-title" id="mini-title">未在播放</span>
5 <span class="mini-artist" id="mini-artist"></span>
6 </div>
7 <button class="mini-toggle" id="mini-toggle">▶</button>
8</div>
迷你挂件通过 postMessage 与 iframe 通信,歌曲信息实时同步。
页面类型识别
音乐页面本身有完整的播放器,不需要迷你挂件;其他页面才显示迷你挂件:
1if (window.location.pathname === '/music/') {
2 // 音乐页面:直接操作完整播放器
3} else {
4 // 其他页面:显示迷你挂件 + iframe
5 initMiniWidget();
6}
多平台歌单
APlayer 原生支持加载远程音乐文件。通过预提取 QQ音乐、网易云音乐、酷狗音乐的歌单接口,将歌曲列表转换为 APlayer 音频数组。歌单 ID 在配置文件中设置,切换歌单时刷新音频列表即可。
性能注意
| 注意点 | 说明 |
|---|---|
| 音频预加载 | preload: 'auto' 会加载整首歌,建议改为 'metadata' |
| 自动播放限制 | 浏览器策略禁止无用户交互的自动播放,需要用户首次手动点击 |
| iframe 通信 | postMessage 消息体积小,对性能无影响 |
| 迷你挂件渲染 | 仅在非音乐页面渲染,减少不必要开销 |
留言评论
期待你的想法评论加载中