Skip to content
dsh.fish
Bundle

dsh-music-player

Vibe coding时的好伴侣

Source
kendu76
weekly downloads
239 weekly downloads
License
MIT
Updated
Updated 7 days ago

Readme

# dsh-music-player

[![Awesome DSH Plugin](https://awesome-dsh-plugin.com/badge.svg)](https://awesome-dsh-plugin.com)

DeepSeek Harness 音乐/小说播放插件。

写代码写累了、想摸鱼又不想切窗口?这个插件就是你的**摸鱼神器**——直接在 DeepSeek Harness 的网页里塞进一个 **DSH音乐播放器**:扫一下你电脑上的音乐目录(默认 `~/Music`)就能在浏览器里听歌,带播放条和可拖拽的播放面板,还能自己建歌单。

光听歌还不够,它还能**听书**:把本地 `.txt`/`.epub` 小说丢给 AI 朗读,想听哪章点哪章、声音随便挑。现在还能**听新闻**:让 agent 用联网搜索收集当天头条(热点/国内/国际/科技/财经/体育/娱乐,或 AI 等任意自定义主题),整理筛选成口播稿用 AI 声音播报——支持每日多定时任务定时、静默收集、文字版阅读。还能**听网络电台**:中文主流台(央广/凤凰/CCTV 伴音等,含 HLS 流)与全球电台一键开播。最绝的是它注册了 `music_play` 等模型工具——你连鼠标都不用动,在对话框里跟 agent 说句「播放周杰伦的歌」,音乐分分钟响起来,摸鱼摸出新境界。

## 特性

- 本地音频流式播放,刷新后断点续播
- 顺序播放、单曲循环、乱序播放三种模式
- 实时频谱可视化,两种样式可在「系统配置」切换(默认柱状图):**柱状图**与**波形图**(示波器式连续曲线,按低/中/高频分成三条层次线)
- **实时歌词/字幕**:本地歌曲自动显示同步歌词——优先读取文件**内嵌歌词**(FLAC `LYRICS`/MP3 `USLT` 标签,无需额外 `.lrc`),其次同名 `.lrc`,都没有时自动在线匹配;在线 QQ 歌曲显示官方歌词(外语歌带逐句翻译);AI 讲书时显示当前朗读句子。**单击播放条歌词**可打开完整歌词/字幕面板(标识当前进度、可拖动/拉伸、位置独立记忆),面板默认开启**透明模式**——歌词像直接悬浮在页面上,可在「系统配置」关闭
- 播放时防止电脑熄屏/休眠(需浏览器支持,如 Chrome/Edge)
- 播放列表面板可自由拖动,右下角可拖拽调整大小,位置与尺寸跨刷新记忆
- AI 讲书:本地 `.txt` / `.epub` 小说 AI 语音朗读,自动识别**书名/前言/章节/尾声**结构,播放条带**章节目录**跳转(打开即定位到当前正在播放的章节)、章节切换,可选 4 种中文 AI 声音(默认白桦)
- `music_play` 模型工具:agent 可按关键词播放本地音乐,也可按小说名启动 AI 讲书
- **每日新闻播报**:agent 用 web search 收集当天头条(可分类别/自定义主题),整理筛选后 AI 语音播报;播放面板「新闻播报」页签随时回看、挑条目播放、看文字版;支持每日多定时任务定时与静默收集(详见下文「每日新闻播报」)
- 支持的格式:`mp3 / m4a / m4b / aac / flac / wav / ogg / opus / webm / aiff`(自动递归扫描子目录,上限 500 首)
- **真实音质识别**:扫描时自动识别每首歌的音质档位,播放条显示「格式 · 音质档」(如 `FLAC · 无损` / `MP3 · 高音质` / `MP3 · 标准`),与在线音乐的音质标签一致
- **自建歌单**:可新建多个歌单,从本地文件(支持多选、可跨目录)添加歌曲;播放条爱心按钮一键收藏到默认歌单「我最喜欢」;歌单作为播放来源时,顺序/乱序循环只在该歌单内进行
- **在线 QQ 音乐**:面板内置「QQ音乐」页签——微信/QQ 扫码登录(解锁 VIP/高音质)、我的歌单/推荐歌单/分类歌单/排行榜/新歌/搜索浏览、卡片式歌单展示、一键收藏到「我喜欢」
- **在线酷狗音乐**:面板内置「酷狗音乐」页签——酷狗 App 扫码登录(解锁高音质)、推荐/分类歌单/排行榜(TOP500 等)/统一搜索/我的歌单,逐字歌词内嵌翻译;详见下文「在线酷狗音乐」
- **在线网易云音乐**:面板内置「网易云」页签——扫码登录后浏览/搜索/播放(免费歌 320k 高音质直链、VIP 歌试听片段)、我的歌单/推荐/分类歌单/排行榜、YRC 逐字歌词与 LRC+逐句翻译;详见下文「在线网易云音乐」
- **网络电台**:面板内置「网络电台」页签——radio-browser 全球开放电台目录(数万台、无登录),按台名/国家/标签搜索,中文电台/热门电台按主题分组浏览、收藏与最近播放;**支持 HLS(m3u8) 电台**(央广/凤凰/CRI/CCTV 伴音等中文主流台),Host 端纯 Node 把 HLS 转成浏览器直接可播的音频流,无新依赖;`music_play` 传 `source=radio` 可按台名直接开播;详见下文「网络电台」

## 截图

| 播放本地音乐 | 播放QQ音乐 |
|:---:|:---:|
| ![播放本地音乐](assets/screenshot-bar.png) | ![播放QQ音乐](assets/screenshot-qq.png) |
| 播放酷狗音乐 | AI讲书 |
| ![播放酷狗音乐](assets/screenshot-kg.png) | ![播放AI讲书](assets/screenshot-spectrum.png) |
| QQ音乐面板 | 酷狗音乐面板 |
| ![播放面板1](assets/screenshot-panel-qq.png) | ![播放面板2](assets/screenshot-panel-kg.png) |

## 安装

需要已安装 `dsh` CLI。

### 从 npm 安装(推荐,已发布到 registry)

```sh
# 把 <profile> 换成实际 profile 名,如 web
dsh plugin --profile <profile> add dsh-music-player
```

### 从 GitHub 安装(备用来源)

```sh
# 把 <profile> 换成实际 profile 名,如 web
dsh plugin --profile <profile> add github:kendu76/dsh-music-player
```

安装后重启 DSH,打开 Web GUI:
- 聊天输入区上方会出现「DSH音乐播放器」播放条
- 点击右侧「列表」按钮打开播放面板
- 在面板顶部点击「选择音乐目录」并选定音乐目录(默认 `~/Music`),自动递归扫描
- 之后可直接在对话框里让 agent 播放,例如「播放周杰伦的歌」

## 配置

插件为「Host 端 + Web 端」双面结构:

- Host 端(`lib/index.js`):音乐扫描、HTTP 流式、歌单 CRUD/持久化、`music_play`/`news_broadcast`/`news_schedule` 工具、AI 讲书(小说结构解析 + TTS 合成)、新闻播报(期次持久化 + 口播稿渲染分块 + TTS 懒合成)
- Web 端(`lib/client.js`):浏览器里的播放条 / 播放面板 / 频谱 / 歌单(收藏、一键清空)/ 讲书控制 / 新闻播报页签

两者由一个 `cordis.patch.yml` 插入 `music-player` 行并自动组对(在 Web 端 `dsh.client` 声明即指回该行名并加载浏览器半体):

```yaml
- insert:
    - id: music-player
      name: 'dsh-music-player'
```

播放模式与音量等播放偏好都保存在 **Host 端**(见下),刷新后当前曲目与进度也会恢复(浏览器的自动播放可能被拦截,点一次 ▶ 即可解锁)。

> **状态持久化(重要)**:**所有**播放状态都持久化在 Host 端文件 `~/.dsh/music-player-prefs.json`,包括:
> 音量、播放顺序、AI 讲书声音、播放范围、面板位置、上次播放的曲目/进度、每本小说的进度、QQ 搜索历史、QQ 面板所在层、QQ「我喜欢」收藏兜底。
> 因此即使在 **dsh-desktop 桌面版**(每次启动随机端口、浏览器存储按源隔离)下,重启后这些状态照样能找回。
> **升级兼容**:旧版本(<0.7)把同样的键存在浏览器 `localStorage` 里。升级后客户端**优先读 Host**,Host 没有的记录会**自动回退读取旧 `localStorage` 副本并迁移进 Host**,升级不丢用户数据。
> 音乐/小说目录、自建歌单、QQ 登录态也持久化在 Host 端(见下文),同样不受影响。

## 自建歌单(收藏)

播放面板「本地音乐」页内新增子标签:**曲库 / ♥ 我最喜欢 / +**,支持自建歌单并把歌单作为播放来源——此时顺序/乱序循环只在该歌单内进行。

- **新建歌单**:点「+」输入名称即建(可建多个)。
- **曲库加入**:在「曲库」列表每首歌行尾有「+」按钮,点击可把该曲加入任一已有歌单,或直接新建歌单加入。
- **添加歌曲**:进入某歌单 → 点「添加歌曲」→ 打开本地文件多选框(可多选、可跨目录)加入歌单;歌单内每首歌支持上移/下移排序与移除。
- **清空歌单**:每个歌单(含「我最喜欢」)详情内都有「清空」按钮,二次确认后一键移除全部歌曲(歌曲文件不会被删除)。
- **收藏**:播放条上的爱心按钮一键把当前曲加入默认歌单「我最喜欢」,再点取消;「我最喜欢」固定不可删除/重命名。
- **播放范围**:在歌单里点歌,则顺序/乱序/单曲循环都在该歌单内;在「曲库」点歌则回到全库循环。
- **命令**:`music_play` 工具新增 `playlist` 参数,可让 agent 直接播放某个歌单(如「播放歌单 我最喜欢」)。
- 歌单数据保存在 `~/.dsh/music-player-playlists.json`,刷新/重启不丢;歌单可包含曲库目录之外的本地音频文件。

## 在线 QQ 音乐

播放面板顶部切到「QQ音乐」页签即可在线听歌。**需先扫码登录**(QQ 登录或微信登录),登录后可浏览/搜索/播放并访问「我的歌单」,VIP 曲目可播高音质。

> **使用声明(重要)**:在线 QQ 音乐功能通过**非官方接口**访问 QQ 音乐资源,所播放/收藏的内容版权归
> 版权方及 QQ 音乐平台所有。本功能**仅供个人学习、技术研究、日常试听使用**,
> **严禁用于任何商业用途、公开传播、二次分发或盈利行为**。使用本功能即表示您已知悉并同意:
> 1. 您应对自己的使用行为及其后果负责;
> 2. 因使用非官方接口登录/播放导致的账号风控、封禁、限流,以及可能引发的法律、版权纠纷,均由使用者自行承担;
> 3. 本项目作者不承担任何因此产生的直接或间接责任。
> 如您不同意以上条款,请勿使用本功能。

- **登录**:两种扫码方式——**QQ 登录**或**微信登录**(推荐)。登录态保存在 Host 端(`~/.dsh/music-player-qq-cookie.json`),刷新/重启不丢;面板右上角可退出登录。
- **浏览**:6 个子页签——**我的歌单 / 推荐歌单 / 分类歌单 / 排行榜 / 新歌 / 搜索**。
  - 我的歌单:登录后展示当前账号的歌单(卡片式),本人创建的歌单卡片右上角可一键删除(二次确认;「我喜欢」不可删除)。
  - 推荐歌单:热门推荐 12 条,底部「加载更多」可续载。
  - 分类歌单:60+ 分类(默认折叠显示 8 个,可展开),每个分类的歌单支持「加载更多」。
  - 排行榜:巅峰榜/地区榜/特色榜等分组,点榜单看歌曲(带榜单封面卡片),榜单歌曲**一次全量加载**(如热歌榜 299 首,无需「加载更多」)。
  - 新歌:新歌速递(最新/内地/港台/欧美/韩国等)。
  - 搜索:搜歌曲与歌单,带搜索历史(Host 持久化,最近 10 条)。
- **播放**:点击任意歌曲即可播放(同一播放条 + 频谱);歌单详情/排行榜详情/新歌速递头部有「**▶ 播放全部**」按钮,一键把整列表加入播放队列、从第一首开始顺序播放;VIP 标识显示在歌名后,行尾显示歌手名。进入歌单/播放列表时自动定位到正在播放的那一首,且正在播放的条目以高亮选中态显示。
- **收藏**:播放条爱心按钮把当前在线曲目收藏到 QQ 音乐「我喜欢」,已收藏歌曲爱心实时点亮。
- **续播**:在线播放进度(当前曲目 + 队列)刷新后自动恢复,点 ▶ 续播。
- 在线曲目不占本地曲库的 500 首上限,与本地/讲书完全隔离。

## 在线酷狗音乐

播放面板侧栏切到「**酷狗音乐**」页签。**需先用酷狗 App 扫码登录**才能试听(未登录可浏览榜单/歌单/搜索,但取链播放需要登录态)。登录后支持:

- **浏览**:推荐歌单(600+ 热门精选)/ 分类歌单 / 排行榜(TOP500、国潮音乐榜等 57 个,榜单歌曲一次全量加载,如 TOP500=500 首)/ 统一搜索(歌曲 + 歌单)/ 我的歌单(可在歌单详情里移除歌曲)。歌单详情与排行榜详情头部同样有「▶ 播放全部」,整列表入队、从第一首顺序播放。
- **逐字歌词**:KRC 逐字行窗口(与 QQ 的 QRC 同级精度),内嵌翻译自动并入歌词显示。
- **高音质**:按「无损 → Hi-Res → 320k → 128k」梯队请求,tracker 按账号权限授予真实档位,播放条显示实际品质标签。
- **续播**:与 QQ 同构——播放进度+队列独立持久化,刷新后自动恢复;单曲取链失败自动跳下一首。
- 登录态保存在 Host 端(`~/.dsh/music-player-kugou-cookie.json`,0600,含设备指纹),刷新/重启不丢。

> **使用声明**:与在线 QQ 音乐相同——非官方接口、仅供个人学习试听、严禁商业用途;
> 账号风控风险由使用者自行承担。技术细节与端点调研见
> [docs/kugou-integration-research.md](docs/kugou-integration-research.md)。

## 在线网易云音乐

播放面板侧栏切到「**网易云**」页签。**需先用网易云音乐 App 扫码登录**(与 QQ/酷狗一致,未登录只显示登录入口),登录后支持:

- **播放**:免费歌曲直接拿 320k 高音质直链播放(播放条显示「网易云 · 高音质」);VIP/数字专辑歌曲仅能播 **45 秒试听片段**(显示「试听」)。
- **浏览**:推荐歌单 / 分类歌单(65 个分类)/ 官方排行榜(飙升榜、新歌榜等 63 个榜单)/ 统一搜索(歌曲 + 歌单,多分型)。歌单详情(含超大歌单,如 200 首的热歌榜自动批量补齐)与榜单详情头部均有「▶ 播放全部」。
- **歌词**:YRC 逐字行窗口(与 QQ QRC / 酷狗 KRC 同级精度,命中时生效);普通歌曲回退整行 LRC,外语歌带逐句翻译(tlyric)与罗马音。
- **我的歌单**:登录后可查看「我喜欢的音乐」与自建/收藏歌单;**公开歌单详情页可一键「☆ 收藏 / ★ 已收藏」**(收藏进「我的歌单」,取消收藏同按钮)。
- **续播**:播放进度 + 队列独立持久化,刷新后自动恢复;单曲版权受限/取链失败自动跳下一首。
- 登录态保存在 Host 端(`~/.dsh/music-player-netease-cookie.json`,0600),刷新/重启不丢。
- 另有「匿名取链」能力保留在后端:agent 用 `music_play` 工具传 `source=netease` 时,未登录也能播免费曲(供对话场景直接点播)。

> **使用声明**:与在线 QQ 音乐相同——非官方接口、仅供个人学习试听、严禁商业用途;
> 账号风控风险由使用者自行承担。技术细节与端点调研见
> [docs/netease-integration-research.md](docs/netease-integration-research.md)。

## 网络电台

播放面板切到「**网络电台**」页签即可在线听全球电台(radio-browser.info 开放目录,**无需登录、无 key**)。子页签:**我的电台(收藏)/ 最近播放 / 中文电台 / 热门电台 / 搜索**。

- **数据源**:radio-browser.info 社区目录(~4 万电台,CC 开放数据),多镜像自动故障转移;按台名/国家/标签/主题搜索或浏览。
- **中文电台 / 热门电台**:按主题分组浏览(中文=全部/新闻/音乐/交通/财经/文艺/故事/体育;热门=全部/音乐/新闻/古典/摇滚/爵士/谈话),「加载更多」分页拉取,会话内缓存切回不重拉。
- **HLS(m3u8) 支持**:央广/凤凰/CRI/CCTV 伴音等中文主流台多为 HLS 流(实测 CN 目录约四成为 HLS)。Host 端纯 Node(`lib/hls.js`)实时解析 m3u8(支持 master 嵌套、防盗链 token 与 scheme-relative URL)→ 逐分片归一化为 AAC(ADTS) 连续流喂给浏览器——兼容 **MPEG-TS 分片**(央广/凤凰/CCTV)与**裸 ADTS 分片**(蜻蜓/喜马拉雅系 .aac,如「华语金曲500首」)两种容器,**无需 hls.js/ffmpeg 任何新依赖**,浏览器 `<audio>` 直接可播(LIVE 直播态/断流自动重连与纯流台一致)。HLS 台在列表显示绿色「HLS」徽章、播放条标「电台 · HLS」。
- **收藏**:点行尾 ♥ 收藏到本地收藏夹(`~/.dsh/music-player-radio.json`),「我的电台」随时回听。
- **命令**:`music_play` 工具传 `source=radio` + 台名/国家,agent 可直接搜台开播(如「播放网络电台 中国之声」)。
- 直播流不 seek、无进度条(LIVE 态);个别台站可能失效或编码特殊(fMP4/加密等非 AAC)时会明确提示换台。

> **合规**:目录为 CC 开放数据,播放的是各电台公开直播流;仅供个人收听,不录制/不二次分发,遵守台站 ToS。设计与实测记录见 [docs/internet-radio-design.md](docs/internet-radio-design.md)。

## AI 讲书

把本地 `.txt` / `.epub` 小说交给 AI 朗读。**AI 语音目前仅支持xiaomi提供方(限时免费),请在设置中配置好再使用此功能。**

### 前置

在 DSH 的模型设置里配置一个xiaomi提供方(含 api key)。未配置时,小说列表会提示"未配置xiaomi提供方"。

### 使用

1. 打开播放面板,切到「小说」标签,点「选择小说目录」选定包含 `.txt` / `.epub` 的目录(默认与音乐目录相同)。
2. 点击某一本小说开始朗读;也可让 agent 用 `music_play` 工具按小说名播放(如「播放《中国制造》」)。
3. 播放条上的讲书控制:
   - **章节目录**(📖 按钮):自动识别全书结构(书名/前言/章节/尾声),点击弹出**位于按钮正上方**的目录(自动定位到当前正在播放的章节),点击任意章节即从该章开头朗读
   - **后退 / 前进**:讲书模式下跳上一章 / 下一章(音乐模式下仍是上一首 / 下一首)
   - **AI 声音**:点音量按钮,在弹层选择声音——冰糖(女)、茉莉(女)、苏打(男)、白桦(男,默认)
   - **全书进度**:播放条底部有一条「已读字符/全书字符」的进度细线,操作时显示「N%」——按已读字数实时计算,无需先合成全书就能给出稳定的整体进度(切块不回退;字符量来自源文本,因此总长总是可知,而总时长得合成完才知道),刷新页面后也会立即恢复显示(无需先点播放)
4. 刷新页面后从上次位置续读(断点续播)。

支持的格式:
- `.txt`(自动识别 UTF-8 / UTF-16 / GBK/GB18030 编码,无需手工转码)
- `.epub`(自动解压并按其目录(spine)顺序把章节转成纯文本朗读;标题/作者取自 epub 元数据,可识别章节结构;加密/DRM 的章节会自动跳过)

## 每日新闻播报

让 agent 用联网搜索收集当天头条,整理筛选成口播稿后用 AI 语音播报。**前置**:DSH 的 web 搜索可用(`web_search`,内置 DeepSeek 搜索提供方);语音播报需配置 xiaomi 提供方(与 AI 讲书共用,未配置时简报仍会生成、只是不可播)。

### 使用

1. **对话即时播报**(收集完立即播放):对 agent 说「**播报今天的新闻**」。它会按类别搜索当天头条(默认热点/国内/国际/科技/财经/体育/娱乐,可任意指定,如「播一下 AI 相关的新闻」)、跨源去重、每条写口播摘要并标注来源,然后自动开播;说「收集一下今天的新闻,先别播」则只生成不出声。
2. **面板回看**:播放面板「新闻播报」页签——期次按时间倒序排列(**当日期次全保留,跨天自动清理**),未播放的标「待播」;点进详情可**播整期 / 播某类 / 点某一条新闻从该条播**;「文字版」按钮可全文阅读(不方便听语音时)。播放条上与讲书一致:📖 类别目录跳转、上/下一类、逐句字幕、AI 声音切换、`N%` 已读进度。
3. **每日定时(Host 自维护)**:在「新闻播报」页签的「⏰ 每日定时」里可视化配置**多定时任务**(如 08:00 / 12:30 / 18:00),每个定时任务可独立指定收集范围与**新闻条数**(1-20,默认 8;选了多个类别时各类别尽量平均分配),并勾选「收集后立即播放」(不勾选 = **静默收集**,只更新简报不出声);也可勾选「**仅工作日执行**」——按工作日历判断:周一至周五**扣除法定节假日**放假不跑、**周末调休补班视为工作日照常**。节假日数据**按需自动联网获取**(仅在到点判断「仅工作日」定时任务、且日历缺失/过期时才查询 timor.tech,失败自动回退内置表/周一至周五),**无需任何手工维护**。**保存即生效**——定时器由插件在 DSH 主机进程内自维护(无需 agent 创建/同步 DSH 定时任务、无需手动开会话),到点自动执行。也可对 agent 说「每天早上 9 点播报新闻」让其引导配置。可在「⏰ 每日定时」里给执行会话选一个**新闻会话模型**(不选则跟随当前活跃会话)。
4. **手动补收**:定时任务行有「▶ 立即执行」——一键自动跑一轮(不等时刻);同一定时任务 10 分钟内重复收集会被自动跳过。
5. **RSS 信源池(可选加强,默认开启,Host 后台自动使用)**:内置 **10 个核心源**(中新网时政/国际/财经/体育/文化/即时/要闻 + IT之家 + 量子位 + 少数派,全部实测今日新鲜、开箱即用、零配置),池条目带可靠发布时间作为第一信源——**每次新闻收集执行前自动懒拉取最新数据**(无后台定时器、无需手动刷新),agent 先从池中筛选(按定时任务范围预筛注入指令),`web_search` 只作补盲(热点榜单、自定义主题、池外突发);某源连续失败自动停用 24h。**无 UI、无需任何配置**——面板不展示信源池,Host 直接在后台使用(详见 RFC `docs/news-rss-pool-rfc.md`)。**关掉信源池也不影响功能**——收集完全退回 web_search,能力不降级。
6. **工具层确定性去重**:`news_broadcast` 提交时对标题归一化 + 相似度比对,自动剔除与**本期次内**或**当日已有期次**重复的条目(notice 透明报告);同一事件多个来源时,更权威源(official > major > secondary > kol)可**升级替换**当日旧期次里的旧条目。**同类任务当天多次执行不会因去重短收**:收集指令会注入【已报条目】清单(今天已播过哪些),且**仅当当天该定时任务已执行过**时才要求每类按目标条数 1.5~2 倍提交候选缓冲去重(首次执行零冗余、不浪费 token);工具层先去重(剔除重复候选)、再按定时任务条数收敛到目标——收集 8 条就播 8 条(详见 RFC §7.5)。

### 一次执行 = 一个会话

- **每次执行(定时到点或手动立即执行)都会新建一个独立的「执行会话」**去收集并绑定结果——上下文干净聚焦、互不干扰,不再有常驻复用会话。
- 执行会话自动归入侧边栏 **「新闻收集」分组**(专属工作区目录 `~/.dsh/news`),不再散落在「未分组」里;分组名可在工作区菜单里随意重命名。
- **每天凌晨 3 点自动清理「今天之前」的新闻**:删除前一天及更早的全部期次与失败记录(不再保留多天新闻),并联动销毁/归档对应的执行会话;**插件每次启动时也会立即检查一次**,存在非今天的新闻就直接清理(清理幂等,手动触发 `POST /dsh-music/news/purge-stale` 走同一入口)。
- 每期次/失败记录都会记录对应的**执行会话 id**;**删除某期新闻时,会连同删除它对应的执行会话**(结果与会话一一对应、可清理)。
- 定时器在 DSH 主机进程内自维护(Node setInterval 读已保存的定时任务偏好),**完全脱离会话存活**——会话销毁不影响每天到点触发;宿主重启后按持久化偏好自动重建定时器。

### 数据与边界

- 收集与整理由 agent 在会话内完成(每次都是新鲜搜索,无常驻爬虫);播报稿由插件端模板渲染。期次持久化在 `~/.dsh/music-player-news.json`,音频不落盘(播放时按块懒合成)。
- **宁缺毋假**:收集失败(如主机断网、搜索服务故障)时该期次不生成、绝不用旧数据顶替;失败原因透传工具错误(不做推断),面板展示并支持补收。仅浏览器离线不影响收集(收集在 DSH 主机进程完成,浏览器没开只影响"出声")。
- 每条新闻必标来源(如「新华社」「微博热搜」);内容由 AI 自动收集整理,以来源报道为准,请自行甄别。

## 开发

需要 Node.js ≥ 20(vitest 建议 20.19+)与 npm。开发依赖:`vitest` + `react`/`react-dom`/`jsdom`(用于前端渲染冒烟测试):

```sh
npm install
npm test        # 跑 vitest 测试套件(Host 单测 + Web 渲染冒烟,共 500+ 用例)
```

修改 `lib/` 后,在本机 profile 里用 link 方式本地调试并验证:

```sh
dsh plugin --profile <profile> add ./   # 或直接改 profile 里的 link 目标
```

项目结构、测试策略与发布流程详见 [CONTRIBUTING.md](CONTRIBUTING.md)。

## 常见问题

**播放没有声音 / 显示"浏览器拦截了自动播放"?**
浏览器安全策略禁止未经交互的音频播放。首次自动播放被拦截是正常的——在播放条上点一次 ▶ 即可解锁,之后恢复播放。

**音乐面板显示"暂无音乐"或"不是有效的音乐目录"?**
点面板顶部「选择音乐目录」,选一个包含音频文件的实际目录(默认 `~/Music`)。目录路径不可读或不存在时会回退到默认目录而不是报错。

**改了音乐目录/新增了歌曲,但列表没更新?**
播放器在启动时扫描一次,并支持手动重扫:点「选择音乐目录」旁边的新增 **「刷新」按钮**,会重新遍历当前目录并更新列表(音乐与小说通用;无需重选目录)。扫描上限 500 首、递归子目录深度上限 4 层。

**`music_play` 工具说"音乐库为空"?**
说明还没有可用的音乐目录。请先打开播放面板,点「选择音乐目录」配置一次。

**小说列表提示"未配置 xiaomi/MiMo TTS 模型"?**
AI 语音目前仅支持 xiaomi 提供方(限时免费)。请先在 DSH 模型设置里配置 xiaomi/MiMo provider(含 api key),再使用讲书功能。

**讲书播放时点后退/前进没反应?**
讲书模式下后退/前进是跳上一章/下一章;如果当前小说没有识别出章节结构(目录按钮提示"暂无章节结构"),则无法跳章,只能整本顺序播。

**听书偶尔"没声音但时间还在走"?**
这种一般是某一段的合成结果异常(返回了退化/静音音频),或瞬时合成失败。0.3.3 起 Host 端会严格校验合成音频(拒绝空数据/非 PCM 等退化 WAV)并自动重试一次瞬时失败,同时把每次合成结果记录在诊断日志里。若再遇到,可访问 `http://<DSH地址>/dsh-music/tts-logs` 查看最近 60 条合成记录(含失败原因、退化音频事件),据此定位具体是哪个块出的问题。

**本地音乐没有 .lrc,歌词是怎么来的?**
播放器会**在线兜底取词**:先用文件名(可带歌手/时长)在 QQ 音乐匿名接口匹配官方歌词(外语歌带逐句翻译),QQ 无果再查 LRCLIB(免费公开歌词库,返回同步 LRC)。结果按曲目在进程内缓存(正命中 6 小时 / 空命中 30 分钟),避免重复请求;无匹配或失败时静默保持无歌词,不影响播放。歌词为版权内容,仅供个人试听。

**有些音乐文件本身就带了歌词,会读取吗?**
会。播放器优先读取音频文件**内嵌歌词**(FLAC/OGG 的 `LYRICS`/`UNSYNCEDLYRICS` 标签、MP3 的 `USLT` 帧),无需额外 `.lrc` 文件,即可直接显示同步歌词。取词优先级为:**同名 `.lrc` → 文件内嵌歌词 → 在线兜底**(同名 `.lrc` 仍是第一优先,其次内嵌,都没有才走在线)。内嵌歌词通常就是标准 LRC 格式(含 `[mm:ss]` 时间戳),与普通 `.lrc` 一样逐句高亮、支持歌词面板。

**本地歌词带翻译(原文/翻译逐句),能显示吗?**
能。若本地 `.lrc`(或内嵌歌词)里是「**翻译行带自己的时间戳、紧跟在原句后**」的写法,播放器会自动识别逐句翻译,并像在线歌词一样合并成「**原文 / 翻译**」显示(播放条与歌词面板都生效)。**支持双向方向**——既支持主流「外文歌 → 中文翻译」:
```
[00:01.00]Sparrows outside the window
[00:01.50]窗外的麻雀
```
也支持「中文歌 → 外文翻译」:
```
[00:01.00]窗外的麻雀
[00:01.50]Sparrows outside the window
```
识别从严:主语言由整首歌词统计决定(外文为主则中文行是翻译,中文为主则外文行是翻译),只有「相邻两行、时间戳接近」的翻译行才会被合并;歌名/水印等中英混杂的杂项行不误判,无翻译的歌词保持原样。

**想支持更多音频格式?**
格式支持由 Host 端 `AUDIO_TYPES` 表驱动,在 `lib/index.js` 里加扩展名与 MIME 即可(播放器本身用浏览器原生 `<audio>` 解码,最终能否播放还取决于浏览器对该编码的支持)。

**新闻播报里的新闻是怎么收集的?来源可靠吗?**
由 agent 在会话里用 `web_search` 联网搜索(内置 DeepSeek 搜索提供方),按类别多查询、跨源去重、只保留可确认时效的条目,每条必标来源(新华社、微博热搜等)。收集在 DSH 主机进程完成——浏览器没开不影响,只是不能出声;搜索服务故障/断网时该期次不生成(宁缺毋假),面板会显示失败原因并支持一键补收。

**新闻定时任务设置了却不触发?**
定时器由插件在 DSH 主机进程内自维护(读面板已保存的定时任务偏好,每 30s 检查一次,到点触发)——**请确认 dsh-desktop / dsh 服务主机进程保持运行**;浏览器没开不影响收集(只影响出声)。每次触发会新建一个执行会话去收集并绑定结果(归入侧边栏「新闻收集」分组)。可在「新闻播报」页签的「⏰ 每日定时」里查看/修改定时任务;保存即生效。

**收集时看到 `web_fetch` 报 `WEB_BLOCKED_URL`(non-public IP)?**
说明本机开着 TUN 代理的 **fake-ip DNS 模式**(Clash/mihomo、sing-box 等):所有域名都会被解析成 `198.18.x.x` 这类代理内部地址,DSH 的 `web_fetch` 防 SSRF 保护会拒绝连接。收集流程会正常尝试抓取原文,但遇到这种报错会自动跳过、降级为只用 `web_search` 摘要继续整理,**新闻照常生成**。想让 `web_fetch` 恢复可用:把代理的 DNS 改为真实 IP 解析即可(Clash/mihomo 设 `enhanced-mode: redir-host`;sing-box 删除 DNS 配置里的 `fakeip`)。

**新闻期次为什么少了 / 旧的去哪了?**
新闻**只保留当天**:每天凌晨 3 点自动删除前一天及更早的全部期次与失败记录(插件启动时也会立即检查一次),并归档对应的执行会话;当日期次全保留,也可以在面板里手动删除。「未听」的期次会带「待播」徽标,方便快速找到漏掉的。

## License

[MIT](LICENSE) © kendu76

Install

dsh plugin --profile web add dsh-music-player@1.0.0

Profile: web

Source