登录
注册
开源
企业版
高校版
搜索
帮助中心
使用条款
关于我们
开源
企业版
高校版
私有云
模力方舟
AI 队友
登录
注册
【活动通知】GOTC 2026 全球开源技术峰会11月14日北京开幕,开源 × AI 生态创新活动,创客、开发者免费报名通道开启!
代码拉取完成,页面将自动刷新
Watch
不关注
关注所有动态
仅关注版本发行动态
关注但不提醒动态
1
Star
0
Fork
0
deepin20
/
音搜
代码
Issues
0
Pull Requests
0
Wiki
统计
流水线
服务
质量分析
Jenkins for Gitee
腾讯云托管
腾讯云 Serverless
悬镜安全
阿里云 SAE
Codeblitz
SBOM
开发画像分析
我知道了,不再自动展开
发行版
标签 (Tag)
全部
全部
正式版
预览版
发行版列表
音搜 Android 2.5.8 — 下载即入媒体库
最新版
音搜 Android 2.5.7 — 首个正式签名版
音搜 2.5.0-10 — 官网定址 yinsou.tuxnav.cn
音搜 2.5.0-9 — 卡片封面 / 滚动歌词 / 歌词校准
音搜 2.5.0 — 每日推荐 / 排行榜 + 歌词系统完善
音搜 2.4.0 — 接入 MPRIS2:系统媒体控件 / 蓝牙耳机 / playerctl 可控
音搜 2.3.0 — 适配统信 UOS 应用商店规范 / 修复无声音
音搜 v2.1.0
音搜 v2.0.0
netmusicplayer v1.2.0
1.1.0
1.0.0
音搜 Android 2.5.8 — 下载即入媒体库
最新版
对比
deepin20
2026-10-20 23:48
android-2.5.8
5aefb22
## 音搜 Android 2.5.8(下载完成即入系统媒体库) | 项 | 值 | |---|---| | 包名 / 显示名 | `cn.tuxnav.yinsou` / 音搜 | | versionCode / versionName | `2508` / `2.5.8` | | 架构 | 仅 **arm64-v8a** | | 系统要求 | Android 8.0+(API 26) | | 大小 | 25,124,992 B | | SHA-256 | `78949bcbb9825d92d7156ffabd8d6a8a69c2453b86b54eb6095f51fd17a100e1` | | 签名 | APK Signature Scheme v2 + v3 | ### 亮点 - **内置聚合服务**:应用内自带 music-dl(arm64),不配电脑也能聚合搜索、看榜单与推荐;也可填电脑/NAS 地址接管(共享电脑侧缓存与登录态) - **本版修复**:下载完成后立刻触发系统媒体扫描,「我的 → 本地」不再需要等索引;- **播放预检 + 自动换源**:某源直链失效时(当前 kugou 上游整体失效,桌面版同样如此)自动换其他平台版本续播,队列里没有就现搜兜底 - **后台播放**:Media3 MediaSessionService,通知栏 / 锁屏 / 蓝牙按键 - **歌词**:滚动歌词 + 全屏歌词(字号可调)+ 可拖动悬浮歌词 - **批量下载**:SAF 目录授权,整榜存 mp3,不申请存储权限 - **收藏 / 最近 / 本地音乐 / 播放模式**(顺序·单曲·随机,与桌面版取值一致) ### 安装提示 - 调试包 `cn.tuxnav.yinsou.dev`(音搜 Dev)可与本包**同机并存**,但两者数据不互通。 - 若提示「签名不一致」,说明机上装着旧签名或旧包名版本,请先卸载再装(会清掉该应用的本地收藏与设置)。 - 快捷校验:`sha256sum yinsou-2.5.8.apk`,与上表对比。 完整说明见仓库 `docs/RELEASE_NOTES_ANDROID_2.5.7.md`。
最后提交信息为:
fix(android): 下载完成后立刻触发媒体扫描,本地列表立即可见(2.5.8)
音搜 Android 2.5.7 — 首个正式签名版
对比
deepin20
2026-10-20 15:09
android-2.5.7
8d8ac43
## 音搜 Android 2.5.7(首个正式签名版) | 项 | 值 | |---|---| | 包名 / 显示名 | `cn.tuxnav.yinsou` / 音搜 | | versionCode / versionName | `2507` / `2.5.7` | | 架构 | 仅 **arm64-v8a** | | 系统要求 | Android 8.0+(API 26) | | 大小 | 25,124,488 B | | SHA-256 | `33e4ed85770a0bc83268b56e1bfcab7c4b83a13fd36a2cab8ca1b2c1ff75a8dc` | | 签名 | APK Signature Scheme v2 + v3 | ### 亮点 - **内置聚合服务**:应用内自带 music-dl(arm64),不配电脑也能聚合搜索、看榜单与推荐;也可填电脑/NAS 地址接管(共享电脑侧缓存与登录态) - **播放预检 + 自动换源**:某源直链失效时(当前 kugou 上游整体失效,桌面版同样如此)自动换其他平台版本续播,队列里没有就现搜兜底 - **后台播放**:Media3 MediaSessionService,通知栏 / 锁屏 / 蓝牙按键 - **歌词**:滚动歌词 + 全屏歌词(字号可调)+ 可拖动悬浮歌词 - **批量下载**:SAF 目录授权,整榜存 mp3,不申请存储权限 - **收藏 / 最近 / 本地音乐 / 播放模式**(顺序·单曲·随机,与桌面版取值一致) ### 安装提示 - 调试包 `cn.tuxnav.yinsou.dev`(音搜 Dev)可与本包**同机并存**,但两者数据不互通。 - 若提示「签名不一致」,说明机上装着旧签名或旧包名版本,请先卸载再装(会清掉该应用的本地收藏与设置)。 - 快捷校验:`sha256sum yinsou-2.5.7.apk`,与上表对比。 完整说明见仓库 `docs/RELEASE_NOTES_ANDROID_2.5.7.md`。
最后提交信息为:
release(android): 首个正式签名版 2.5.7 + 发版说明
音搜 2.5.0-10 — 官网定址 yinsou.tuxnav.cn
对比
deepin20
2026-10-19 19:32
2.5.0-10
e1a69ec
## 音搜 2.5.0-10 本次是一个小修订:**软件官网正式定址**,并上线了独立的宣传站点。 ### 官网 - 官网地址改为 **https://yinsou.tuxnav.cn/** ,与导航站 tuxnav.cn 分开部署、互不影响。 - 该地址已写入安装包的 `Homepage` 字段、AppStream 元数据的 `<url type="homepage">`, 以及软件内「设置 → 关于 → 官网」按钮,点开即是宣传站。 ### 宣传站 收录了功能总览、界面截图、版本亮点与下载入口;所有截图都是程序真实界面离屏渲染, 不是设计稿拼贴。站点源码随仓库一起开源(`website/`)。 ### 打包 - 宣传站不随安装包分发(它是独立部署的静态站点)。上一个包因目录收集规则漏了这一条, 体积被撑到 9.8 MB;本版回落到 8.83 MB,并补了回归测试盯住这条规则。 安装包:`io.gitee.deepin20.netmusicplayer_2.5.0-10_amd64.deb`(amd64,适用 Deepin / UOS) 测试:562 passed
最后提交信息为:
release: 音搜 2.5.0-10 —— 官网定址 yinsou.tuxnav.cn
音搜 2.5.0-9 — 卡片封面 / 滚动歌词 / 歌词校准
对比
deepin20
2026-10-19 17:52
2.5.0-9
643318d
## 音搜 2.5.0-9 本版主线:**歌单/榜单显示真实封面**、**主窗口滚动歌词**、**歌词校准就地可调**。 ### 歌单与排行榜封面 - 卡片原来只有首字色块占位,现在后台异步拉取真实封面(并发 ≤ 6、同地址合并、圆角 120px)。 - 修「封面永远停在占位块」:同一封面地址被并发请求时,后到的调用方现在能一起拿到结果, 不再被直接丢弃。 - 封面是相对路径时自动补成绝对地址,镜像 / 代理部署同样能显示。 ### 主窗口滚动歌词 - 原来 80px 的文本框换成滚动歌词视图:长句按宽度自动折行,当前行加粗放大、用系统强调色 高亮并居中滚动。 - 歌词区与歌曲列表之间可拖动分隔条,自己决定歌词占多高。 ### 歌词校准入口搬家 - 「词- / 词+ / 改词」从顶部工具栏移到两个顺手的位置: - 主窗口歌词面板的标题行(旁边显示当前偏移); - 桌面歌词右键 →「歌词同步(±x.x 秒)」子菜单(提前 / 延后 0.5 秒、归零、编辑当前歌词)。 - 切歌会自动恢复这首歌记住的偏移,界面各处跟着刷新(此前只改内存、显示还是上一首的值)。 ### 桌面歌词 - 字号上限放宽到 120,新增「上方居中 / 下方居中」,窗口高度按行数自适应,双行大字不再被裁。 - 右键菜单可直接调字号、字重、单双行、颜色、位置、置顶、锁定位置。 - 主窗口最小化或收进托盘后,桌面歌词继续保持置顶。 ### 稳定性 - 修切换音源时的崩溃:歌手加载线程被回收后仍去查询运行状态,会抛 RuntimeError 直接中止进程。 - 去掉样式表里 Qt 不支持的描边 / 阴影属性(启动终端会刷一屏警告),描边改用图形效果实现, 这次是真的生效了。 ### 其他 - 官网改为 https://tuxnav.cn/ ,与代码仓库地址分开维护;设置里的「官网」与「关于」都指向这里。 安装包:`io.gitee.deepin20.netmusicplayer_2.5.0-9_amd64.deb`(amd64,适用 Deepin / UOS) 测试:561 passed
最后提交信息为:
release: 音搜 2.5.0-9 —— 卡片封面 / 滚动歌词 / 歌词校准
音搜 2.5.0 — 每日推荐 / 排行榜 + 歌词系统完善
对比
deepin20
2026-10-17 20:58
2.5.0
ba803a6
# 音搜 2.5.0 发布说明 本次两条主线:**推荐歌单 / 排行榜**(接入 music-dl 1.1.2)与**歌词系统完善**。 > 适用安装包:`2.5.0-3`(修订记录见文末)。版本号中的 `-N` 是 Debian 修订号, > 代码有改动就会递增,`2.5.0` 本身代表功能集。 文中的数量均为**实测快照(2026-10-19)**。推荐歌单与榜单由各平台动态提供, 具体条数会随时间变化,不必视为固定值。 --- ## 一、推荐歌单与排行榜 侧栏新增两个入口,数据来自随包携带的 music-dl(已升级到 **1.1.2**): | 入口 | 内容 | 实测(2026-10-19) | |------|------|------| | **推荐歌单** | 按平台浏览**公共**推荐歌单,双击进入曲目 | 102 个(网易云 30 / 酷狗 30 / 酷我 30 / QQ 12) | | **排行榜** | 各平台榜单(飙升、新歌、原创、热歌…) | 202 个(网易云 64 / 酷狗 55 / 酷我 36 / QQ 29 / 咪咕 18) | 点开任一歌单或榜单,曲目直接灌入主列表,可以「全部播放」「下载选中」「加入队列」, 与搜索结果的用法完全一致。 > **「推荐歌单」不是网易云 App 的「每日推荐」**:后者是个人化接口,需要登录态、 > 每天推 30 首;本版取的是各平台的公共推荐歌单,无需登录。侧栏因此用 > 「推荐歌单」命名,避免按个人化推荐的预期去找。 ### 页面解析 music-dl 的 Web 端是**服务端渲染**,接口返回类型并不统一: | 路由 | 返回 | |------|------| | `/music/search`、`/music/toplists`、`/music/toplist_songs`、`/music/recommend`、`/music/playlist_songs` | 服务端渲染的 **HTML** | | `/music/inspect`、`/music/switch_source` | **JSON** | | `/music/download` | **音频流**(Range 透传,可直接交给播放器) | | `/music/lyric` | **纯文本**歌词 | 本版不改上游源码,只消费它的页面,新增 `core/gomusic_html.py` 做解析 (纯字符串运算,不依赖 Qt / 网络,可单测)。 - 榜单卡片**没有 `data-*` 属性**,id 与来源只能从 `href` 的 query 里取; 推荐卡片的完整信息则在「导入本地」按钮的 `data-*` 上。两种结构分别处理。 - 解析器踩过一个坑:`\b` 是**零宽单词边界断言**,`card` 末尾的 `d` 与 `-` 之间存在边界,所以 `\bplaylist-card\b` 在 `playlist-card-actions` 上也成立, 每张卡片被切成两半、`data-*` 全落在块外。现在用 `(?![\w-])` 收口—— 要求 class 名后面必须紧跟真正的结束位置。 ### sidecar 版本陷阱与升级路径 排行榜是 music-dl **1.1.2 才有的**,1.1.1 上 `/music/toplists` 直接 404。 而旧版本实例会占着端口: - 复用前现在会额外探测 `/music/toplists`,路由不存在就判定版本过旧; - 判定过旧后,**会主动结束那个进程**(仅当 `/proc` 里确认它是 `music-dl web -p <端口>`,且端口匹配;不是就老老实实顺延端口)。 这一步是必要的:旧实例属于上一个已经退出的程序,`atexit` 早已跑过, 不收掉它会一直占着 27183 直到重启系统,而且每次启动都因它顺延一个新端口。 实测环境里,升级后第一次启动即可在原端口拉起 1.1.2,不再残留。 ### 两个只有真实环境才会暴露的问题 - **本机请求被送去代理**:`requests` 默认 `trust_env=True`,会把发往 `127.0.0.1` 的 sidecar 请求也交给用户环境里的 `http_proxy`。代理连不到 用户的回环地址,表现是「搜索、推荐、榜单全空,而日志里 sidecar 明明活着」。 现在访问 sidecar 一律走关掉 `trust_env` 的专用 `Session`。 - **首次请求偶发断连**:sidecar 刚拉起的一两秒里,Go 侧 socket 已 accept 但 handler 还没就绪,实测会偶发 `RemoteDisconnected`。单次失败就退化成 「暂无数据」,在界面上与「真的没有榜单」完全无法区分。现在统一重试一次。 --- ## 二、歌词系统 ### 1. 自动多源回退(按歌曲来源短路) 以前「哪个源就走哪条取词路,失败就显示暂无歌词」,聚合搜索换到酷狗/QQ 的歌 经常整首没词。现在按优先级依次尝试,**首个成功即停**: | 歌曲来源 | 尝试顺序 | |---------|---------| | 本地文件 | 本地 `.lrc` → LRCLIB(本地文件没有平台 id,不走 music-dl) | | 聚合源(`via=gomusic`,含 QQ / 酷狗 / 酷我 / 咪咕) | **music-dl** → 网易云 API(仅有 id 时)→ LRCLIB | | 原生网易云 | **网易云 API** → music-dl → LRCLIB | 顺序按来源短路而不是固定「music-dl 永远排第二」:对原生网易云的歌,先问 music-dl 只会白拉一次 sidecar(惰性启动,首次最长等 30 秒)却拿到同一份词; 对聚合源的歌则相反——只有 music-dl 知道对应平台的歌词。 全程后台线程,带代次校验;切歌后才回来的旧结果会被丢弃,不会串词。 ### 2. 偏移校准 工具栏新增 `词-` / `词+`:每按一次 ±0.5 秒,范围限制在 ±10 秒。 **按歌曲记忆**,存: ``` ~/.local/share/io.gitee.deepin20.netmusicplayer/lyric_offsets.json ``` (遵循 `$XDG_DATA_HOME`,上面是默认位置。) 写入是原子的:先写 `lyric_offsets.json.tmp`、`fsync` 后再 `os.replace`, 避免写一半断电留下坏 JSON。`common/cache_manager.py` 的 `_write` 用的也是 同一套「临时文件 + replace」,两处口径一致。 ### 3. 逐字歌词 解析 KTV 格式(`[00:12.00]我[00:12.30]们`)时保留每个字的时间戳: - **桌面歌词窗口**:当前行拆成「已唱 / 未唱」两段双色渲染,逐字推进; - **内嵌歌词框**:仍为整行显示(`QTextEdit` 按纯文本展示,不做逐字着色)。 时间精度要如实说明:播放位置由 `player.py` 的定时器驱动,**每 500 ms 一次** (本版未改这个间隔),所以逐字高亮的实际粒度是 **0.5 秒**,不是「每个字准时 跳色」。逐字进度只在「已唱字数变化」时才发信号,避免每 500ms 都刷一次界面。 没有逐字数据时退回整行高亮,行为与以前一致。 ### 4. 编辑与导出 工具栏 `改词` 打开编辑框: - 可直接改文本与时间戳,点「应用」立即生效。**只影响本次播放**,切歌即失效; 要长期保留请「导出 .lrc」。编辑框顶部有这条提示。 - 时间轴顺序:解析阶段就会按时间排序,所以「应用」后顺序一定正确。但用户 手改敲反两行时,这个修正会被明确告知(「第 N 行时间戳小于上一行,已按时间 轴排序」),不会静默改掉用户的输入。导出前再排一次,作为最后一道保险。 - 「导出 .lrc」写入带 `[ti:]/[ar:]/[al:]` 头的标准 LRC,并校验内容里是否 真有时间轴(没有就提示,避免导出无法同步的文件)。 ### 5. 无时间轴的歌词 LRCLIB 会返回两种歌词:`syncedLyrics`(带时间轴)与 `plainLyrics`(纯文本)。 本版**优先 `syncedLyrics`**,为空时才退到 `plainLyrics`。 纯文本歌词以前会被解析器整段丢弃(没有时间戳就无法定位),界面显示 「暂无歌词」——明明取到了词却说没有。现在按文本展示,并在末尾标注 「(无时间轴,不滚动)」,状态栏同时提示,用户不会误以为歌词卡住了。 --- ## 三、其他 - **版本**:`2.4.0-2` → `2.5.0-1`;文档与若干修复随后并入 `-2` / `-3` (见文末修订记录)。 - **随包 sidecar**:music-dl `1.1.1` → `1.1.2`。 - 二进制:30,961,956 B → 31,240,376 B(**+272 KB**); - deb 安装包:8,731,908 B → 8,819,956 B(**+约 85 KB**,压缩后); - `music-dl --version` 回报 `v1.1.2`。 - **依赖未变**:本版 `Depends` 与 2.4.0 完全一致,无新增 Python 依赖。 三个新模块只用了标准库与已有的 PyQt5 / requests (`core/lyrics.py` 纯函数、`core/gomusic_html.py` 纯字符串、 `ui/lyric_editor.py` 用 Qt)。安装体积 31,504 KB → 31,837 KB。 - **新增模块**:`core/lyrics.py`(解析 / 时间轴 / 导出)、 `core/gomusic_html.py`(页面解析)、`ui/lyric_editor.py`(编辑对话框)。 - **测试**:相对 2.4.0 新增 49 例(含本次审查后的 16 例回归),全量 **461 passed**,**全部离线**——sidecar 页面 解析用固定 HTML 夹具,接口层用注入的假函数,`_fetch_page` 全部被 monkeypatch,不依赖真实网络或真实 sidecar。 - **打包健壮性**:`dpkg-deb --build` 改为先写 `<包名>.part` 再原子替换。 原来直接写目标路径,而 dpkg-deb 会**先截断目标再开始写** —— 构建一旦失败 (TMPDIR 不可用、磁盘写满),`dist/` 里就留下一个 0 字节、文件名却完全 正确的 .deb,发布脚本会把它当真包传上去。 - **测试基建**:`test_no_maintainer_scripts` 改用 `dpkg-deb --ctrl-tarfile` 读内存 tar 索引,不再依赖解包权限 —— 在无 `utime` 权限的沙箱/只读挂载上 原来会误报失败(`dpkg-deb -e` 其实已经把文件解出来了,只是退出码为 2)。 --- ## 安装 ```bash sudo apt install ./io.gitee.deepin20.netmusicplayer_2.5.0-3_amd64.deb ``` 适配统信 UOS / Deepin(amd64)。推荐歌单与排行榜需要随包的 music-dl 二进制, 安装包已内置,无需额外操作。 ### 升级须知(从 2.4.x 升级请务必阅读) **安装后请完全退出应用(含托盘图标)再重新启动。** 原因:`apt` / `dpkg` 只会替换磁盘上的 `music-dl` 二进制,**正在运行的旧版 sidecar 进程仍在内存里**,并且占着 27183 端口。不重启应用的话,旧进程会继续 服务请求 —— 搜索正常、排行榜与推荐歌单却不可用。 2.5.0-3 起应用会主动收掉这类旧实例(判定条件见上文),所以正常情况下 「重启一次」就够了。若仍异常,可执行: ```bash pkill music-dl # 结束所有残留实例 ``` 再启动应用即可。日志位置: `~/.local/share/io.gitee.deepin20.netmusicplayer/gomusic/logs/music-dl.log`, 排查时搜关键词「版本过旧」。 ## 已知限制 - 推荐歌单与排行榜依赖各平台接口的可用性;某个平台临时挂掉时该源的卡片 会为空,不影响其它源。 - **个人化**的每日推荐(需登录态、按账号推荐)不在本次范围,当前为平台公共推荐。 - 部分需要登录态的榜单/歌单(如「我喜欢的音乐」)不在本次范围。 - 从推荐/榜单「下载选中」时,曲目是否可下载取决于对应音源当时的可用性。 不可用的会被跳过,并在状态栏提示 —— 可能出现「选了 10 首只下了 6 首」。 - 逐字高亮的粒度为 0.5 秒(受播放位置刷新间隔限制),不是逐字精确跳色。 --- ## 附:sidecar 二进制的校验口径 `go-music-dl_checksums.txt` 里列的是**发布资产(.tar.gz / .deb / .rpm)**的 哈希,不是解压出来的 `music-dl` 可执行文件。对不上号时不要以为文件被改过: ```bash # 校验的是这个(上游清单里的那一行) sha256sum go-music-dl_linux_amd64.tar.gz # b78abe4ec2b378bbd1b7fd5cca97e580556d7419a06870449eb5306390fa2efb ← 在清单里 # 解出来的二进制是另一个哈希,清单里没有,属正常 sha256sum music-dl # f8b74d36130504e269ba9141dcf2ccfafeb5ce4cb83d8da048e39047af0edede # 最终确认真身靠 --version music-dl --version # → music-dl version v1.1.2 (TUI Version) ``` 包内 `opt/apps/<appid>/files/bin/music-dl` 的哈希应为 `f8b74d36…0edede`(31,240,376 B)。 --- ## 修订记录 | 包 | 变更 | |----|------| | `2.5.0-1` | 首个包。推荐歌单 / 排行榜 + 歌词四项 | | `2.5.0-2` | **修复**:推荐/榜单曲目漏打 `via=gomusic` 标记,播放必失败(「音乐接口请求失败」)。同时含卡片视图视觉优化(副标题不截断、双击后标题换成榜单名)与打包原子性改进 | | `2.5.0-3` | **修复**:① 歌词源链按歌曲来源短路(原生网易云不再先拉 sidecar);② LRCLIB 纯文本歌词不再显示成「暂无歌词」;③ 导出前时间轴顺序二次校验、「应用」时如实告知重排;④ 旧版 sidecar 实例会被主动收掉,不再永久占用端口。**文案**:「每日推荐」→「推荐歌单」。**文档**:本说明按审查意见全面修订(路由返回类型、升级须知、实测日期、路径、体积、测试离线性等) |
最后提交信息为:
release: 音搜 v2.5.0 —— 每日推荐 / 排行榜 + 歌词系统完善
音搜 2.4.0 — 接入 MPRIS2:系统媒体控件 / 蓝牙耳机 / playerctl 可控
对比
deepin20
2026-10-17 19:48
2.4.0
ebe3f46
新增桌面集成能力:播放器现在可以被系统媒体控件、蓝牙耳机与 playerctl 操控。 ## 本次重点 **MPRIS2 桌面媒体集成(零新增依赖)** 在 `/org/mpris/MediaPlayer2` 上同时导出 `org.mpris.MediaPlayer2` 与 `org.mpris.MediaPlayer2.Player` 两个接口: - 控制:`PlayPause` / `Play` / `Pause` / `Stop` / `Next` / `Previous` / `Seek` / `SetPosition` / `OpenUri` - 状态:`PlaybackStatus` / `LoopStatus` / `Shuffle` / `Metadata` / `Position` / `Volume`,以及 `Can*` 能力位 - 元数据:歌名、歌手、专辑、时长、封面(`mpris:artUrl` 指向本地缓存) 实现走 QtDBus(`QDBusAbstractAdaptor`),**不引入 pydbus / dbus-python**,`Depends` 一行未改。 验证: ```bash playerctl -p netmusicplayer metadata xesam:title playerctl -p netmusicplayer play busctl --user introspect org.mpris.MediaPlayer2.netmusicplayer /org/mpris/MediaPlayer2 ``` **过程中修掉的一个隐蔽 bug**:`PropertiesChanged` 的 `invalidated_properties` 规范要求是 `as`,而 PyQt5 把 Python 列表一律封成 `av`。签名错了客户端会**整条丢弃**该信号 —— 表现是「控制正常、歌在播,但任务栏歌名永远不刷新」。现在用 `QVariant(QVariant.StringList)` 封装,测试里有断言守着。 ## 其他改动 - 封面缓存:`$XDG_CACHE_HOME/<appid>/covers`,原子写入、6MB 上限、同 URL 去重,失败不影响播放 - 搜索结果补 `album.picUrl` → `extra['cover']` - 设置项 `ui/mpris_enabled` 可关闭;无 DBus 或注册失败时静默降级 - 版本 2.3.0 → 2.4.0(deb `2.4.0-2`);新增测试 52 例,全量 368 通过 ## 安装 ```bash sudo apt install ./io.gitee.deepin20.netmusicplayer_2.4.0-2_amd64.deb ``` 适配统信 UOS / Deepin(amd64);需要 `libvlc5` + `vlc-plugin-base`(缺后者会「能播放但没声音」)。
最后提交信息为:
release: 音搜 v2.4.0 —— 接入 MPRIS2 桌面媒体集成
音搜 2.3.0 — 适配统信 UOS 应用商店规范 / 修复无声音
对比
deepin20
2026-10-07 22:33
2.3.0
4fe91c7
适配统信 UOS 应用商店规范,并修复 deb 安装后播放没有声音的问题。 ## 本次重点 **包名改为反向域名** `io.gitee.deepin20.netmusicplayer`(原 `netmusicplayer` 不是反向域名)。 商店要求 Package 为反向域名,且 AppStream 对非反向域名的 `<id>` 会报 `cid-is-not-rdns(error)`, 元数据会被软件目录丢弃。现在七处标识一致,并改成了构建硬校验。 **修复:deb 安装后播放没有声音。** 真实根因有两层: 1. `Depends` 缺少 `libvlc5` / `vlc-plugin-base`(音频输出插件在其中)—— 缺插件时 libvlc 能"播放"却完全不出声,且不报错; 2. libvlc 的音频输出是**异步**创建的,早于它的 `audio_set_volume` 会被静默丢弃。 而 `volume_slider.setValue(80)` 又发生在信号连接之前 —— 结果界面滑块显示 80、 libvlc 实际音量是 0(静音)。现在会在确认播放后补设音量。 新增自检命令(可直接定位"没声音"的成因): ```bash python3 main.py --check-audio # 插件/音频模块/设备/音源可用性 python3 main.py --check-audio 某首歌.mp3 # 再用程序自身播放链路测一次 ``` ## 其他改动 **合规与打包** - 数据/缓存改为 XDG 目录 `$XDG_*_HOME/<appid>`,不再直写 `$HOME`(商店退件项之一),含旧数据自动迁移 - 零维护脚本、`/opt/apps/<appid>/{files,entries,info}` 布局、AppStream 元数据、 DEP-5 copyright(含 AGPL 声明)、9 档 PNG + SVG 图标、`Installed-Size`、root/root 属主 - 不再打包测试套件 **界面(适配 UOS 原生观感)** - 默认跟随系统深浅色(gsettings → Qt 调色板),设置项「跟随系统」 - 强调色改为运行时读取系统强调色,不再写死 `#409eff` - 移除写死的 `font-family`,尊重用户系统字体 - 修复外部 QSS 因路径写错而从未被加载的问题 **桌面集成** - 文件关联(MimeType + `Exec %F`)、拖拽导入、已运行实例的文件投递 - 系统托盘(关闭收进托盘、切歌通知;无托盘会话自动降级) - 下载完成后写入标签/封面/歌词(mp3/flac/m4a/ogg) **清理**:移除 `downloader/`、`ui/signals.py`、`ui/crawler_tab.py`、crawler 演示脚本, 以及仓库中误跟踪的运行时残留(`.Trash-0`、`.workbuddy`、`songs_33ve.json` 等)。 ## 归档 上一版本(2.1)已归档:分支 `archive/2.1`,标签 `2.1.0`。 ## 测试 275 项回归测试全部通过。
最后提交信息为:
发布 2.3.0:适配统信 UOS 应用商店规范
音搜 v2.1.0
对比
deepin20
2026-09-25 22:59
2.1.0
05b3819
# NetMusicPlayer 2.1.0 发布说明 > **发布日期**:2026-09-25 > **兼容性**:Deepin 20+ / UOS 20+ / Ubuntu 18.04+(amd64) > **包文件名**:`netmusicplayer_2.1.0-1_amd64.deb`(约 8.3 MB) > **升级方式**:`sudo dpkg -i dist/netmusicplayer_2.1.0-1_amd64.deb` --- ## 🎯 版本亮点 2.1.0 是继 2.0.0 之后的**功能补完版本**,核心是让 go-music-dl 聚合后端从"能跑"变成"好用"——引入了**按源分组、三层激进换源、逐字歌词、扫码登录入口**四项关键改进,并修复了 2.0.0 暴露出的三个稳定性问题。 | 关键指标 | 2.0.0 | 2.1.0 | |---------|-------|-------| | 聚合音源 | 6 个 | 6 个(不变) | | 换源策略 | 单层(演唱者完全匹配) | **三层**(完全一致 / 包含 / 忽略演唱者) | | 结果展示 | 混合列表 | **按源分组** | | 歌词格式 | 标准 LRC | **标准 + 逐字 KTV** | | 网易云登录 | 无入口 | **设置里一键打开 Web 界面** | | sidecar 稳定性 | 每次搜索重启 | **全程复用同一实例** | --- ## ✨ 新增功能 ### 1. music-dl 聚合后端管理入口 **设置 → 网络 → music-dl 聚合后端** 新增独立分组,包含: - **实时状态显示**:`运行中` / `未启动` / `未找到可执行文件` - **▶ 打开管理界面**:内嵌 `QWebEngineView`(若已安装 `PyQtWebEngine`),否则回退到系统浏览器打开 `http://127.0.0.1:<port>/music` - **⟳ 刷新状态**:无需重启应用即可重新检测后端 - **☰ 打开日志**:直接打开 sidecar 日志目录,方便排查问题 **关键价值**:在打开的 music-dl 网页里可以 **扫码登录网易云**,登录后 `netease` 源的直链解析成功率显著提升。登录凭证保存在 `~/.local/share/netmusicplayer/gomusic/settings.db`,重启应用后仍然有效。 ### 2. 三层激进换源 当聚合源的主源解析失败时,自动尝试**同一首歌在其他源**的版本。三层试探策略(从最严格到最宽松): | 层级 | 匹配条件 | 说明 | |------|---------|------| | **第 1 层** | 归一化标题相等 + 演唱者完全一致 | 最安全,首选 | | **第 2 层** | 归一化标题相等 + 演唱者包含关系 | 处理合作曲目(如 `周杰伦 / 袁咏琳` vs `周杰伦`) | | **第 3 层** | 归一化标题相等 + **忽略演唱者** | 激进模式,用于原唱版本全挂、只剩翻唱的场景 | **标题归一化规则**:自动剥离括号内容(`(Live)`、`(伴奏)`、`[Remix]` 等)和版本后缀词,让 `东方之珠 (Live)`、`东方之珠 - 伴奏`、`东方之珠` 归为同一首歌。 **关闭方式**:在 `Config` 里设置 `GOMUSIC_AGGRESSIVE_SWITCH = False` 只保留前两层。 ### 3. 搜索结果按源分组显示 聚合搜索的多源结果**自动按音源分组**,每组前插入一条不可交互的标题行: ``` ♪ 网易云 · 9 首 心雨 - 毛宁、杨钰莹 ♪ [浪漫情歌对唱] 04:38 心雨 - 高胜美 ♪ [经典金曲1哭砂] 04:39 ... ♫ QQ 音乐 · 6 首 心雨 - 杨钰莹;毛宁 ♪ [流行对唱嘴对嘴] 04:38 ... ♩ 酷狗 · 9 首 ... ♬ 酷我 · 6 首 ... ♪ 咪咕 · 20 首 ... ``` **交互细节**: - 组标题**不可勾选、不可双击、不可拖拽**(防止误操作) - 单源结果(本地 / 33ve / 网易云)**保持平铺**,不引入视觉干扰 - 组内顺序、跨组勾选下载/加队列等原有功能完全保留 ### 4. 逐字 LRC 歌词支持 兼容 **Enhanced LRC / KRC** 逐字歌词格式——原本的: ``` [00:01.04]毛[00:01.12]宁、[00:01.20]杨[00:01.27]钰[00:01.35]-[00:01.42]心[00:01.50]雨 ``` 现在会被正确解析为: ``` 毛宁、杨钰莹 - 心雨 ``` **同时过滤 LRC 元信息标签**:`[ti:]` `[ar:]` `[al:]` `[by:]` `[offset:]` `[length:]` `[kana:]`,避免这些非歌词内容出现在歌词区域。 ### 5. 版本号动态读取 设置 → 关于的版本号现在从 `version.py` 动态读取,**发版只需修改一处**,避免以后再次出现"关于页版本号与实际包不一致"的问题。 --- ## 🐛 关键修复 ### 1. sidecar 反复重启(严重) **症状**:每次搜索都启动新的 music-dl 进程,PID 不断变化,日志里出现 `music-dl 子进程已退出(code=-15)`。 **根因**:`PR_SET_PDEATHSIG` 绑定的是**创建子进程的那个线程**,而不是"父进程"。sidecar 是在搜索任务的**工作线程**里惰性拉起的,一旦该线程返回(搜索完成),内核就把 sidecar 当作孤儿进程,立即发 `SIGTERM`。 **修复**:移除 `preexec_fn`,只保留 `start_new_session=True`(会话隔离)。孤儿进程由 `atexit` 正常清理;异常崩溃留下的残留实例,下次启动时会被 `_healthy` 检测并复用。 **效果**:三次搜索共用同一个 sidecar(PID 不变),后续搜索响应时间从 1~3 秒降到毫秒级。 ### 2. 聚合搜索结果时长全部为 00:00 **症状**:`心雨`、`东方之珠` 等所有歌曲的时长都显示 `00:00`。 **根因**:music-dl 的 `data-duration` 属性单位是**秒**(实测《东方之珠》= 258 秒),而我们把它当毫秒处理。 **修复**:在 `search()` 里 `duration_sec * 1000` 转毫秒。 ### 3. emoji 在 Deepin 字体下渲染为方块 **症状**:`🌐 打开管理界面` 显示成 `☒ ...`、`🔄 刷新状态` 显示成乱码等。 **根因**:Deepin 的默认字体(Noto Sans CJK SC / 文泉驿微米黑)不覆盖部分 emoji 字形。 **修复**:用 **Unicode 音符符号**替代 emoji: | 原 emoji | 新符号 | |---------|-------| | 🌐 🔄 📄 💡 | ▶ ⟳ ☰ ✱ | | 🎵 🎼 🎤 🎸 🎧 🎶 | ♪ ♫ ♩ ♬ ♪ ♫ | 这些符号在所有 Linux 字体上都能正常渲染。 --- ## ⚙️ 新增配置项 `config.py` 新增以下字段(均可在设置对话框或 `QSettings` 中调整): | 配置项 | 默认值 | 说明 | |--------|-------|------| | `GOMUSIC_ENABLED` | `True` | 聚合后端总开关 | | `GOMUSIC_BINARY` | `""` | 空 = 自动探测(`/usr/bin/music-dl` → `bin/music-dl`) | | `GOMUSIC_PORT` | `27183` | 首选端口(冲突时自动向后顺延 5 个) | | `GOMUSIC_DATA_DIR` | `~/.local/share/netmusicplayer/gomusic` | sidecar 数据目录 | | `GOMUSIC_SOURCES` | `netease,qq,kugou,kuwo,migu,qianqian` | 参与聚合的音源 | | `GOMUSIC_STARTUP_TIMEOUT` | `30` | 首次拉起 sidecar 的超时(秒) | | `GOMUSIC_AGGRESSIVE_SWITCH` | `True` | 是否允许跨演唱者换源(第三层) | --- ## 📦 打包与集成 ### 架构声明 由于随包携带 `bin/music-dl`(amd64 二进制),`control` 里的 `Architecture` 字段现在是动态的: - 带 sidecar → `amd64` - 不带 sidecar(自行禁用聚合)→ `all` ### 版权合规 新增 `debian/copyright` 声明,明确 `bin/music-dl` 为 **AGPL-3.0** 二进制,以 **mere aggregation** 方式集成(独立进程调用、不修改源码、不静态链接)。 ### 启动时自动修复权限 `postinst` 脚本增加 `chmod 0755 /opt/netmusicplayer/bin/music-dl` 兜底,防止某些文件系统/挂载选项丢失可执行位。 --- ## 🔧 升级指南 ### 从 2.0.0 升级 ```bash # 1. 卸载旧版本 sudo dpkg -r netmusicplayer # 2. 清理旧残留(dpkg 卸载时会跳过非空目录,需要手动清) sudo rm -rf /opt/netmusicplayer # 3. 安装 2.1.0 sudo dpkg -i dist/netmusicplayer_2.1.0-1_amd64.deb # 4. 验证 dpkg -l netmusicplayer # 应显示 2.1.0-1 ``` ### 配置兼容性 - 2.0.0 的 `QSettings` 配置**完全兼容** - 首次启动会自动填充新增配置项的默认值 - 如需恢复出厂设置:设置对话框 → 恢复默认 ### 首次使用建议 1. 打开 **设置 → 网络 → music-dl 聚合后端** 2. 点击 **▶ 打开管理界面** 3. 在网页里 **扫码登录网易云** 4. 关闭网页,回应用搜一首歌,验证 netease 源解析成功率提升 --- ## ⚠️ 已知限制 ### 1. 网易云匿名直链不稳定 即使不登录,music-dl 也能"看到"网易云的歌曲 ID,但直链请求有时会返回 404。这是网易云从 2024 年起对匿名用户收紧策略的结果。**登录后情况会显著改善**。 ### 2. ARM 架构需要自行编译 `bin/music-dl` 是 amd64 二进制。如果需要在 ARM 平台运行,需要从 [go-music-dl](https://github.com/guohuiyuan/go-music-dl) 源码自行编译,并替换 `bin/music-dl`。 ### 3. 首次启动 sidecar 需要 3~20 秒 第一次触发聚合搜索时,music-dl 需要初始化 SQLite、编译模板、与上游握手。后续搜索共用同一实例,无需重复等待。 ### 4. 描边样式在部分 Qt 版本下输出警告 `-webkit-text-stroke` 和 `text-shadow` 是 WebKit 专用属性,Qt 不支持,会输出 `Unknown property` 警告。不影响功能。 --- ## 📊 性能数据 | 指标 | 数值 | |------|-----| | 首次 sidecar 启动 | 3~20 秒(视网络) | | 后续搜索响应 | 毫秒级(内存复用) | | 单次 probe_download | 1~2 秒 | | 三层换源总耗时(含探测) | 2~6 秒 | | .deb 包体积 | 8.3 MB(含 30 MB 二进制压缩) | | 安装后占用 | 约 35 MB | --- ## 🙏 致谢 - [go-music-dl](https://github.com/guohuiyuan/go-music-dl) — 提供多平台聚合能力 - [NeteaseCloudMusicApi](https://github.com/Binaryify/NeteaseCloudMusicApi) — 自部署网易云 API - [python-vlc](https://github.com/oaubert/python-vlc) — 音频播放引擎 - [LRCLIB](https://lrclib.net/) — 歌词服务 --- ## 📮 问题反馈 反馈时请附上: - 终端日志(`netmusicplayer 2>&1 | tee /tmp/nmp.log`) - sidecar 日志(设置 → 网络 → ☰ 打开日志) - 复现步骤和期望行为 --- **感谢使用 NetMusicPlayer 2.1.0!** 🎵 *本版本遵循 GPL-3.0 协议发布,集成的 go-music-dl 组件遵循 AGPL-3.0。*
最后提交信息为:
更新代码
音搜 v2.0.0
对比
deepin20
2026-09-25 11:30
2.0.0
73cca1b
# 📦 NetMusicPlayer 2.0.0 更新说明 > 发布日期:2026-09-25 > 兼容性:Deepin 20+ / UOS 20+ / Ubuntu 18.04+(amd64) > 版本号来源:`version.py` --- ## ✨ 版本亮点 **2.0.0 是一次架构级升级**,核心变化是引入了 [go-music-dl](https://github.com/guohuiyuan/go-music-dl) 作为本地 sidecar,实现了**多平台音乐聚合搜索与播放**。同时,播放控制、歌词、设置、打包等模块做了系统性重构。 | 关键指标 | 1.2.0 | 2.0.0 | |---------|-------|-------| | 在线音源 | 网易云 + 33ve 爬虫 | 网易云 + 33ve + **QQ / 酷狗 / 酷我 / 咪咕 / 千千** | | 播放模式 | 仅顺序播放 | 顺序 / 单曲 / 随机 | | 歌词 | 静态展示 | 同步滚动 + 高亮 + 桌面悬浮 | | 设置项 | 约 5 项 | 约 20 项(含桌面歌词完整配置) | | 包体积 | ~500 KB | ~8.3 MB(含 sidecar 二进制) | --- ## 🎧 新功能 ### 1. 多平台聚合搜索(Powered by go-music-dl) - 顶部音乐源下拉框新增「**🎧 聚合搜索**」选项 - 一次搜索,同时查询 **网易云 / QQ 音乐 / 酷狗 / 酷我 / 咪咕 / 千千** 六大平台 - 搜索结果保留原始音源标识,便于辨别来源 - 播放/下载走 sidecar 代理 URL,支持**惰性换签名直链**(不会因为直链过期而失效) - sidecar 二进制随包分发(`/opt/netmusicplayer/bin/music-dl`,v1.1.1) **使用方式**:切换到「🎧 聚合搜索」源 → 输入关键词 → 双击播放。 ### 2. 网易云降级策略 - 自部署 NeteaseCloudMusicApi 无法响应或无结果时,**自动降级**到聚合搜索 - 播放时自部署 API 解析不出直链 → 回退到 go-music-dl 代理 - 下载时聚合优先(带 `probe_download` 预检),自部署 API 兜底 ### 3. 播放模式 底部控制栏新增模式按钮,**中文显示 + 颜色区分**: - 🔵 **顺序** → 循环播放整个队列 - 🟢 **单曲** → 当前歌曲循环 - 🟠 **随机** → 洗牌播放 ### 4. 一键静音 - 音量滑块旁新增静音按钮,图标随状态切换 🔇 / 🔊 - 取消静音时恢复之前的音量 ### 5. 停止按钮 - 独立红色「停止」按钮,一键停止播放并重置进度 ### 6. 全部播放 - 「▶ 全部播放」将当前列表**整个加入播放队列**,而不是只播第一首 --- ## 🎤 歌词功能全面升级 ### 1. 歌词同步滚动 - 播放时自动高亮当前行(蓝底白字) - 歌词视图自动跟随滚动 ### 2. 桌面悬浮歌词 - 独立无边框窗口,可任意拖动 - 支持**单行 / 双行**显示模式 - **总在最前** / **锁定窗口**(禁止拖动) - 支持通过 ESC 键关闭 ### 3. 完整歌词设置(设置对话框 → 桌面歌词) | 分类 | 可配置项 | |------|---------| | 显示 | 位置(左上/右上/左下/右下/居中)、显示模式(单行/双行) | | 字体 | 字体族、字号(12–60px)、字重(标准/粗体/半粗/细体) | | 样式 | 描边开关、主色、次色、背景色、次色透明度 | | 行为 | 锁定、总在最前 | | 预览 | 实时预览字体/颜色/透明度效果 | ### 4. 手动获取歌词 - 工具栏新增「📝 获取歌词」按钮 - 输入歌手 + 歌名,从 [LRCLIB](https://lrclib.net/) 获取 - 支持外文歌词(无翻译/音译功能) ### 5. 本地歌词自动读取 - 播放本地音频时自动查找同目录 `.lrc` 文件 - 支持多编码:UTF-8 / GBK / GB18030 / Big5 / Latin-1 - 支持模糊匹配(去除扩展名后精确比对) --- ## 🖥️ 界面重构 ### 1. 移除菜单栏 原有菜单(文件/歌词/帮助)的**全部功能整合到工具栏**: - 「📂 打开文件」→ 工具栏 - 「📝 获取歌词」→ 工具栏 - 「关于」→ 设置对话框底部 - 移除了无效的「账号」菜单 ### 2. 播放队列 - 侧边栏新增播放队列视图,实时反映当前队列 - 双击队列中的歌曲可跳转播放 ### 3. 本地音乐 - 使用 `mutagen` 读取完整的元数据(标题/艺术家/专辑/时长/封面) - 「➕ 添加到播放列表」追加到队列(不清空已有队列) ### 4. 设置对话框重构 - 采用 **QTabWidget** 分组:网络 / 目录 / 界面 / 桌面歌词 - 增加**滚动区域**,保证所有控件可见 - 增加「**恢复默认**」按钮,一键重置所有配置 - 主题切换**即时生效**(无需保存) --- ## ⚙️ 系统集成 ### 1. 输入法环境自检 启动时自动检测 Qt 版本与输入法插件兼容性,输出诊断日志: ``` Qt 版本 : 5.15.8 PyQt5 路径 : /usr/lib/python3/dist-packages/PyQt5 QT_IM_MODULE : fcitx 输入法插件 : libfcitx5platforminputcontextplugin.so 输入法可用 : 是 ``` ### 2. 配置持久化(QSettings) 所有设置保存到 `~/.config/SoundSearch/NetMusicPlayer.conf`,包括: - API 地址、代理设置、本地音乐目录、下载目录 - 主题、桌面歌词字体/颜色/位置 - go-music-dl 相关开关 ### 3. 进程管理 - sidecar 惰性启动(首次用到才拉起) - Linux `prctl(PR_SET_PDEATHSIG)` 防止主进程崩溃后 sidecar 变孤儿 - 端口冲突自动顺延(最多 5 个备用端口) - 退出时 `atexit` 自动清理 --- ## 📦 打包改进 ### 1. 架构声明 - 携带 sidecar 二进制时,包架构自动标记为 `amd64` - 不携带时为 `all` ### 2. 依赖自动安装 `postinst` 脚本自动通过 apt 安装: ``` python3-bs4, python3-fake-useragent, python3-tqdm, python3-mutagen ``` 失败时回退到 `pip3` 安装 `beautifulsoup4 / fake-useragent / tqdm / cloudscraper`。 ### 3. 版权合规 - 新增 `debian/copyright` 声明 - 明确 `bin/music-dl` 为 **AGPL-3.0** 二进制,以 **mere aggregation** 方式集成 ### 4. 版本号统一 - 版本号唯一来源:项目根 `version.py` - 打包时自动改写 `.desktop` 的 `Version` 行为当前版本 ### 5. 目录整洁 - 打包时排除 `third_party/`(Go 源码) - 打包时排除开发期数据(`songs_33ve.json`、`downloaded_cache.json`) --- ## 🔧 修复的问题 - 修复:`QFont` 未导入导致的 `NameError` - 修复:`settings_dialog.py` 中颜色属性未初始化导致的 `AttributeError` - 修复:`lyric_window.py` 文件编码损坏导致的 `SyntaxError` - 修复:缓存管理器 `_enforce_size_limit` 边界条件 - 修复:VLC 库与 PyQt5 版本冲突(推荐使用系统 PyQt5) - 修复:`update_lyric_by_index` 未正确调用导致的歌词不高亮 - 修复:`[Music]` 文本噪音,改用专辑图标 - 修复:状态栏不显示播放状态(已中文化:播放中/已暂停/已停止/已结束) - 修复:`从网络获取歌词` 未实现的空操作 - 修复:`全部播放` 只播第一首的问题 --- ## ⚠️ 已知问题与限制 ### 1. 网易云直链解析 从 2024 年起,网易云对匿名用户收紧直链解析。**未登录状态下**: - 聚合搜索的网易云结果会显示「无效」 - 建议优先使用 QQ / 酷狗 / 酷我等音源,或切换到自部署 NeteaseCloudMusicApi 源 ### 2. 架构限制 `bin/music-dl` 是 **amd64** 二进制。ARM 平台(如某些国产化终端)需自行编译对应架构。 ### 3. 包体积 sidecar 二进制约 30 MB(未压缩),最终 `.deb` 包约 8 MB。相比 1.2.0 增加明显。 ### 4. 首次搜索延迟 首次触发聚合搜索时,sidecar 需要 1–3 秒启动。后续搜索共用同一实例。 ### 5. 桌面歌词描边 描边效果依赖 `-webkit-text-stroke`,在部分 Qt 版本上会输出 `Unknown property` 警告(不影响功能)。 --- ## 📥 升级指南 ### 从 1.2.0 升级 ```bash # 1. 卸载旧版本 sudo dpkg -r netmusicplayer # 2. 清理旧残留(重要!卸载时 dpkg 会跳过非空目录) sudo rm -rf /opt/netmusicplayer # 3. 安装 2.0.0 sudo dpkg -i dist/netmusicplayer_2.0.0-1_amd64.deb # 4. 验证 sidecar 二进制 /opt/netmusicplayer/bin/music-dl --version # 预期输出:music-dl version v1.1.1 (TUI Version) # 5. 启动 netmusicplayer ``` ### 配置兼容性 - 1.x 的 QSettings 配置**完全兼容** - 首次启动会自动填充新增配置项的默认值 - 如需恢复出厂设置:设置对话框 → 恢复默认 --- ## 📄 许可证变更 - **主程序**:GPL-3.0(不变) - **集成组件 `bin/music-dl`**:AGPL-3.0(go-music-dl 项目) - 集成方式:**独立进程调用(mere aggregation)**,不修改其源码,不与其静态链接 - 完整的版权声明见 `/usr/share/doc/netmusicplayer/copyright` --- ## 🙏 致谢 - [go-music-dl](https://github.com/guohuiyuan/go-music-dl) — 提供多平台聚合能力 - [NeteaseCloudMusicApi](https://github.com/Binaryify/NeteaseCloudMusicApi) — 自部署网易云 API - [python-vlc](https://github.com/oaubert/python-vlc) — 音频播放引擎 - [LRCLIB](https://lrclib.net/) — 歌词服务 --- ## 📮 反馈 - 项目仓库:`~/Desktop/Gitee/音搜/netmusicplayer` - 问题反馈:请附上终端日志(`netmusicplayer 2>&1 | tee /tmp/nmp.log`) --- **感谢使用 NetMusicPlayer!** 🎵
最后提交信息为:
自动同步 2026-09-22 01:01:08
netmusicplayer v1.2.0
对比
deepin20
2026-09-22 00:59
1.2.0
2339343
# UOS 网络音乐播放器 1.2.0 更新说明 | 项目 | 内容 | |------|------| | 版本号 | **1.2.0**(deb 版本串 `1.2.0-1`) | | 发布日期 | 2026-09-22 | | 适用平台 | 统信 UOS 20+ / Deepin 20+ / Ubuntu 18.04+ | | 安装包 | `netmusicplayer_1.2.0-1_all.deb`(124,676 字节,73 个文件 / 不含目录项) | | 依赖变更 | 新增 `mutagen`;`cloudscraper` 补登记;移除未使用的 `aiohttp` | --- ## 一、一句话概览 1.2.0 是**修复性版本,不含新功能**。它只解决三件「功能明明写在界面上、实际却用不了」的事: 1. 搜索框**打不出中文**,甚至可能直接崩溃; 2. 点歌手**爬不到歌**,报 `No module named 'cloudscraper'` 或「获取 0 首」; 3. 歌能列出来,但**点播放没声音**。 顺带修掉一个更隐蔽的问题:打出来的 `.deb` 包是个**空壳包**(装得上、起不来),以及一次爬取失败会被缓存锁死 28 天。 --- ## 二、重点修复 ### 1. 搜索框无法输入中文 · 严重 **现象**:搜索框敲中文没反应,或程序启动即报 `Cannot mix incompatible Qt library (5.11.3) with this library (5.15.19)` 后退出。 **根因**:能不能打中文,取决于「运行时 Qt 版本」与「输入法前端插件的 Qt 版本」是否一致。pip 安装的 PyQt5 自带 Qt 5.15,而系统里的 fcitx 前端 `libfcitxplatforminputcontextplugin.so` 是按系统 Qt 5.11 编译的 —— 两者不一致时,插件要么加载不上,要么强行加载后 Qt 直接 abort。 **处理**:新增 `common/im_env.py`,启动时自动比对 Qt 版本并做适配: - 版本不匹配时,把 `PyQt5` / `sip` **定向**切换到系统 dist-packages 的那份(只动这两个包,不影响 `requests` / `vlc` / `mutagen`); - 自动选并设置 `QT_IM_MODULE` / `XMODIFIERS`; - 顺带修掉两个体验问题:输入法**组合态**按回车不再被误当成「搜索」提前触发(`ui/toolbar.py` 新增 `SearchLineEdit`);关键词里的全角空格 `U+3000`、全角字母数字和零宽字符会自动规范化(`common/utils.py` 新增 `normalize_keyword()`)。 **自查命令**: ```bash python3 main.py --check-ime # 打印运行时 Qt 版本、输入法前端及其 Qt 版本、最终选用的 QT_IM_MODULE export NETMUSICPLAYER_NO_IME=1 # 需要时关闭自动配置 ``` ### 2. 点击歌手爬取失败 / 只拿到 0 首 · 严重 **现象**:状态栏报 `爬取失败: No module named 'cloudscraper'`;装上依赖后又变成「获取 0 首歌曲」。 **根因**:这不是一个 bug,是三层叠在一起: | 层 | 问题 | 说明 | |----|------|------| | 1 | **依赖缺失** | `cloudscraper` 既没装、也没写进 `requirements.txt`,导入爬虫模块时直接抛 `ModuleNotFoundError`;同类漏登记的还有 `fake-useragent`、`tqdm` | | 2 | **站点加了人机验证** | 33ve 在页面之前插了一层「安全人机验证」(带 `csrf_token` 的复选框表单)。它**不是 Cloudflare**,没有 JS 挑战,cloudscraper 的绕过能力对它完全无效 | | 3 | **解析函数是空实现** | `parse_songs_from_singer_page()` 与 `find_max_page_for_singer()` 原本只有占位注释和 `return 1`,前两层都过了也只会返回 0 首 | **处理**:新增 `crawler/site_session.py` 作为统一会话网关,并补全解析逻辑: - 自动识别并提交人机验证(同一 Session 先 GET 取 `csrf_token`,再 POST `human_check=on`);验证状态按 Cookie 缓存约 1 小时,后续点击不再重复验证; - `cloudscraper` 缺失时自动降级为 `requests.Session`,不会再把 `ModuleNotFoundError` 冒到状态栏; - 分页改为「逐页递增抓取 + 遇到空页即停 + 按 id 去重」——站点分页区显示的页码比实际大,不可信; - 爬取结果自动并入本地歌曲库 `~/.music_search_data/songs_33ve.json`,否则爬到的歌只在当次列表里,回搜索框依然搜不到。 ### 3. 歌曲能列出,点播放没声音 · 严重 **根因**:库里存的是下载入口 `https://www.33ve.com/plug/down.php?ac=music&id=...`。该入口同样受人机验证保护——裸请求返回 **403**;通过验证后才会 **302** 跳到酷狗真实音频直链(`sharefs.tx.kugou.com/...`)。把入口 URL 直接交给 VLC 是拿不到声音的。 **处理**:播放/下载前用已验证的会话实时换取直链(`CrawlerSource.resolve_play_url()`)。目标直链带时效签名,因此**只用于本次播放、不写回数据库**,每次播放都重新解析。 ### 4. `.deb` 打包出来是空壳 · 严重(仅影响构建) **现象**:包能装上,但里面没有 `main.py`,装上起不来;`.desktop` 与图标也一直走兜底分支。 **根因**:`scripts/build_deb.py` 的 `project_root` 被算成了 `scripts/` 目录本身。 **处理**:`resolve_project_root()` 改为以 `main.py` 为锚点向上查找;打包后**断言**包内确实含有入口文件,缺失则构建失败(不再静默产出坏包);`.desktop` 与图标的查找改为候选列表;排除 4.1 MB 的 `crawler/songs_33ve.json` 以免把开发数据打进发行包。 ### 5. 一次爬取失败 = 28 天不再重试 · 中等 **根因**:旧逻辑无论成功失败都写 `last_crawl` 时间戳,而歌手缓存有效期是 28 天(`SINGER_CRAWL_CACHE_DAYS`)——一次网络抖动就能让这个歌手在近一个月内被判定为「已爬过」而永久跳过。 **处理**:改为**只有真正抓到歌曲才写** `last_crawl`。爬取期间会写 `crawl_cache.json`。 > **升级提示**:如果你在 1.2.0 之前遇到过「明明还没爬到却提示已缓存」,可删掉 `~/.music_search_data/crawl_cache.json` 让缓存重置,或等其自然过期。 --- ## 三、新增能力一览 | 能力 | 位置 | |------|------| | 启动时自动适配输入法环境(零配置) | `common/im_env.py` | | `--check-ime` 输入法诊断开关 | `main.py` | | `NETMUSICPLAYER_NO_IME=1` 关闭自动适配 | 环境变量 | | 关键词规范化(全角/零宽/空白折叠) | `common/utils.py` | | 人机验证自动提交 + Cookie 缓存 | `crawler/site_session.py` | | 播放/下载直链实时解析(不落盘) | `models/music_source.py`、`core/controller.py` | | 爬取结果自动并入本地歌曲库 | `crawler/crawl_songs.py` | | 版本号单一来源 | `version.py` | **版本号单一来源**:此前版本号散落在多处、容易改漏,现已抽成根级 `version.py`(纯标准库,不依赖 PyQt5,构建期也能读取)。「关于」对话框、`setup.py` 元数据、deb 版本号与包内 `.desktop` 的 `Version` 行都从这里读。**改版本只需改这一个文件。** --- ## 四、安装与升级 ```bash # 安装/升级 sudo dpkg -i netmusicplayer_1.2.0-1_all.deb # 源码运行时的依赖(新增 mutagen、cloudscraper) pip3 install --user -r requirements.txt ``` 依赖变化: - **新增** `mutagen>=1.45.0`(`controller.py` 读取本地音频标题/时长,此前漏登记); - **补登记** `cloudscraper>=1.2.71`(缺失时自动降级,不装也能跑)、`fake-useragent`、`tqdm`; - **移除** `aiohttp`(代码中并未实际使用,下载走 `requests` + 线程池;且 Python 3.7 装不了 3.9+ 版本); - deb `Depends` 同步为:`python3, python3-pyqt5, python3-pyqt5.qtmultimedia, python3-vlc, python3-requests, python3-mutagen, vlc, python3-pip`。 --- ## 五、验证情况 - **测试**:`pytest tests/` → **77 passed**(其中 1.2.0 新增测试 4 个文件、约 1000 行:`test_im_env.py`、`test_crawler_33ve.py`、`test_build_deb.py`、`test_version.py`)。 - 关键修复均做了**反向验证**(把实现改回旧行为,确认测试确实会失败):空实现 → 4 项失败;失败写缓存 → 1 项失败;只抓 1 页 → 1 项失败;去掉打包断言 → 构建检查失败;版本号四个回退场景全部被捕获。 - **实测抓取**:林俊杰 488 首、周杰伦 359 首、邓紫棋 501 首;本地歌曲库约 1.2 MB。 - **实测播放**:VLC 经 302 直链播放正常。 --- ## 六、已知问题与遗留 | # | 问题 | 状态 | |---|------|------| | 1 | 桌面歌词窗口为占位按钮,功能未实现 | 计划中 | | 2 | `main.py` 尚无 `--version` 开关(版本号已是单一来源,加一行即可) | 待补 | | 3 | deb 包内仍包含 `tests/` 目录(运行时不读取,可排除) | 待优化 | | 4 | `scripts/build_deb.py` 的 `MAINTAINER` 仍是占位符 `Your Name <your@email.com>` | 发布前需替换 | | 5 | 歌曲 `title` 字段为「歌手 - 歌名」格式,与 `artist` 字段存在冗余 | 待评估 | | 6 | 未在真实 X 会话 + fcitx 运行环境下做最终人工确认 | 建议实测 | --- ## 七、主要文件变动 **新增** ``` common/im_env.py 输入法环境自适应(583 行) crawler/site_session.py 会话网关:人机验证 / 直链解析(344 行) version.py 版本号唯一来源(35 行) tests/test_im_env.py tests/test_crawler_33ve.py tests/test_build_deb.py tests/test_version.py ``` **修改** ``` main.py 启动时 bootstrap();--check-ime;环境变量开关 ui/toolbar.py SearchLineEdit:组合态处理 common/utils.py normalize_keyword() crawler/crawl_songs.py 补全两个空解析函数;逐页去重;直链解析;仅成功写缓存 crawler/crawl_singers.py 依赖可选导入 crawler/proxy_pool.py fake_useragent 可选导入 crawler/main_crawler.py list[str] | None → Optional[List[str]](Python 3.7 兼容) models/music_source.py resolve_play_url() / reload_cache() / 抓取落盘 core/controller.py 播放与下载改用实时直链 scripts/build_deb.py project_root 修正;装箱断言;版本号与 .desktop 联动 setup.py / requirements.txt 版本号读取;依赖清单修正 ui/settings_dialog.py 「关于」读取版本号 netmusicplayer 启动器优先使用 /usr/bin/python3 README.md FAQ 重写(中文输入、爬取三层根因、播放直链) ``` --- **作者**:温暖断章 · **协议**:GPL-3.0
最后提交信息为:
自动同步 2026-09-22 00:58:33
1.1.0
对比
deepin20
2026-07-23 23:41
1.1.0
327fc65
更新:优化本地播放功能(此版本针对deepin25优化,不兼容其它版本)
最后提交信息为:
ui
1.0.0
对比
deepin20
2026-07-22 23:09
1.0.0
7201898
| 功能模块 | 说明 | |---------|------| | **在线搜索** | 通过网易云音乐 API 搜索歌曲、歌手、专辑,支持中文/英文关键词 | | **本地播放** | 支持 `.mp3` / `.flac` / `.wav` / `.m4a` 等常见音频格式 | | **播放列表** | 支持右键删除、清空列表,可添加本地文件或在线歌曲 | | **内嵌歌词** | 主窗口内显示当前歌曲的 LRC 格式歌词(网易云源) | | **播放控制** | 播放/暂停、上一首/下一首、音量调节、进度拖拽 | | **主题切换** | 浅色/深色两套主题 | | **单实例** | 只允许一个播放器进程运行 | | **高 DPI 适配** | 自动适配高分屏,界面清晰 | | **爬虫支持** | 可爬取 33ve 音乐网站歌手和歌曲(实验性) | | **下载管理** | 批量下载歌曲文件 |
最后提交信息为:
add README.md.
下载
请输入验证码,防止盗链导致资源被占用
取消
下载
Python
1
https://gitee.com/deepin20/NetMusicPlayer.git
git@gitee.com:deepin20/NetMusicPlayer.git
deepin20
NetMusicPlayer
音搜
点此查找更多帮助
搜索帮助
Git 命令在线学习
如何在 Gitee 导入 GitHub 仓库
Git 仓库基础操作
企业版和社区版功能对比
SSH 公钥设置
如何处理代码冲突
仓库体积过大,如何减小?
如何找回被删除的仓库数据
Gitee 产品配额说明
GitHub仓库快速导入Gitee及同步更新
什么是 Release(发行版)
将 PHP 项目自动发布到 packagist.org
仓库举报
回到顶部
登录提示
该操作需登录 Gitee 帐号,请先登录后再操作。
立即登录
没有帐号,去注册