给 Astro 静态站加上背景音乐和「非公开文章」
给 Astro 静态站加上背景音乐和「非公开文章」
本站最近做了两个小升级:全站背景音乐播放器,和文章的非公开(draft)机制。两者都不复杂,但各有几个容易踩坑的点,记录下来供参考。
一、背景音乐:先解决版权,再谈实现
个人网站放音乐,第一件事不是写播放器,而是确认曲子能不能用。直接拿流行歌曲的音频文件放到自己服务器上,是明确的侵权行为——即使是个人小站也一样。
可行的来源大致三类:
- CC 授权乐曲:如 Kevin MacLeod 的 incompetech,上千首曲子全部 CC BY 授权,商用也允许,唯一义务是署名。
- 公版乐曲:作曲家去世超过保护期(中国/欧盟一般为死后 50/70 年)的作品本身进入公有领域,比如巴赫、萨蒂。但要注意:曲谱公版 ≠ 录音公版,某个具体演奏录音仍有自己的邻接权,需要找明确以 CC 或公版方式释出的录音。
- 免版税音乐库:如 Free Music Archive 上标注 CC 的曲目,注意区分 CC BY、CC BY-NC(禁止商用)等具体条款。
本站选了 incompetech 的三首,刚好覆盖三种情绪:
| 曲目 | 风格 | 说明 |
|---|---|---|
| Gymnopédie No. 1 | 古典 | 萨蒂名曲,Kevin MacLeod 演奏版 |
| Deliberate Thought | 氛围钢琴 | 阅读时的安静背景 |
| Airport Lounge | 轻松节拍 | 偏 Lounge 的松弛感 |
音频文件直接放在 public/music/ 下走静态托管。三首共约 14 MB,按需加载(preload="none"),不播放就不产生流量。
署名是 CC BY 的硬性义务,本站做了两层:播放器面板底部一行小字,页脚再加一行全站署名,均链接到 incompetech 和 CC BY 4.0 协议原文。
二、播放器的几个实现要点
播放器是一个纯前端的 .astro 组件,挂在 BaseLayout 里,全站生效。核心决策:
不自动播放。 现代浏览器本来就禁止无用户交互的自动播放,贸然 autoplay 只会吃一个 rejected promise。做法是默认暂停、折叠成左下角一个圆形按钮,用户主动点开。
用 localStorage 记忆状态。 Astro 是多页应用,每次跳转页面音频都会重新加载。把当前曲目、音量、是否播放中、面板是否展开存进 localStorage,页面加载后恢复曲目和音量;如果之前正在播放,尝试 audio.play() 续播——浏览器阻止了就安静地保持暂停,不打扰用户。
audio.play().then(function () {
// 续播成功
}).catch(function () {
// 浏览器阻止自动播放:保持暂停状态即可
});
音量默认值压低。 默认 40% 音量,背景音乐不应该盖过内容本身。列表循环播放,放完自动切下一首。
功能上就是播放/暂停、上一首/下一首、进度条点击跳转、音量滑条、曲目列表切换,全部原生 <audio> API 实现,零依赖。
三、非公开文章:draft 机制的完整改造面
需求是:有些文章只想”知道链接的人能看到”,不出现在任何公开入口里。
实现上拆成两层:
1. 页面照常生成,但加 noindex。 在 content collection 的 schema 里加 draft: z.boolean().optional(),draft 文章的页面依然构建(直链可访问),但通过 <meta name="robots" content="noindex, nofollow"> 告诉搜索引擎不要收录。这个标记从 frontmatter 一路透传:BlogPost.astro → BaseLayout.astro → BaseHead.astro。
2. 所有列表入口过滤。 这是容易漏掉的部分——draft 文章必须从每一个聚合页面里排除。本站需要改的地方有七处:
- 博客列表页
blog/index.astro - 首页最新文章
index.astro - 归档页
archive/index.astro - 标签索引与标签详情
tags/index.astro、tags/[tag].astro - 站点地图页
sitemap.astro - RSS 订阅
rss.xml.js - 文章页的上一篇/下一篇导航与相关文章推荐
blog/[...slug].astro
漏掉任何一处,“非公开”就名存实亡——尤其是 RSS 和上一篇/下一篇导航,最容易被忽略。
最后给 draft 文章页顶部加了一条横幅提示(“本页仅可通过直链访问”),避免分享链接的人产生误解。
四、小结
两个功能加起来不到四百行代码,但各自的核心都不在代码上:音乐的关键是版权来源与署名义务,draft 的关键是穷尽所有列表入口。希望对你自己的站点也有参考价值。
💬 留言