🐋 在深水里靠声音辨路。
原生 iOS 与 macOS 音乐播放器,让搜索、收藏与聆听回归纯粹。
界面预览 · 功能 · 运行与安装 · 从源码构建 · 数据与音源 · 致谢
当前 iOS 源码使用封面大图主页、「首页 / 资料库」两个导航入口与悬浮播放条。播放、收起和收藏等控件恢复圆形玻璃按钮及原有按压反馈,主页保留两枚填充操作按钮。启动动画按封面显现、黑胶滑出、品牌出现与黑胶回收分段推进;播放页自底部整体展开,换歌时封面淡入并过渡背景颜色。播放页保留歌词、队列和音质选择;搜索仍在原页遮罩中展开,不显示音源筛选控件。
截图为此前使用 iPhone 17 Pro 模拟器拍摄的界面,未覆盖最新导航与输入法调整。当前仅启用网易云音源,其他音源隐藏并停止调用;旧收藏保留并标记为「不可用」。最新 iOS 预览包包含这些源码调整,下载与安装方式见下文。
- 本地音乐播放:支持导入本地音频文件或文件夹(MP3、FLAC、M4A、WAV 等),自动读取 ID3 元数据、艺术家、专辑与内嵌封面,自动匹配同目录下的同名 .lrc 同步歌词。无需任何第三方凭据与网络即可离线畅享原生播放体验。
- iOS 聆听界面:分段黑胶启动动画、封面大图主页、圆形玻璃播控与原有按压反馈;播放页整体展开,换歌时封面与背景平滑过渡。
- 音乐搜索:一个搜索框查询网易云结果,保留原页面遮罩交互;QQ、酷狗等其他音源暂时隐藏并停用,已有收藏仍保留。
- iOS 输入法兼容:搜索框自动处理首次键盘显示后的重新聚焦,无需在设置中手动开启;组合输入期间不触发自动搜索。第三方输入法需先在系统键盘设置中启用。
- iOS 桌面小组件:中号「正在播放」小组件支持切换随机播放,按钮状态与 App 播放模式同步。
- 封面与歌词:播放页随封面取色,支持明暗外观、同步歌词与逐字高亮;缺少逐字时间时会明确标注合成效果。
- 本地歌单:用 SwiftData 保存收藏和歌曲信息,支持 JSON 导入、导出与重复歌曲去重。
- 播放队列:支持下一首播放、加入待播,以及随机、单曲循环、顺序播放和列表循环。
- Mac 随手播控:状态栏选歌面板与顶部播放器共享播放、收藏状态,支持悬停展开、封面、歌词、进度和音量控制;取消收藏提供确认高亮与收起动画。
- 最高音质优先:网易云通过 ChKSz 从母带音质开始,缺少可用结果时逐级尝试 Hi-Res、无损、320K、128K,保持同一歌曲 ID。
- 歌单迁移:粘贴网易云音乐的公开歌单链接或 ID,预览后按原顺序合并,自动跳过已收藏歌曲。
Sonar 没有开屏广告或内置社交页面。本地音乐完全离线读取;在线歌曲、封面和歌词来自第三方服务,可用性与实际播放音质取决于歌曲和音源;歌单备份保存歌曲信息,不包含音频文件。
Sonar is a native SwiftUI music player for iOS 17+ and macOS 14+. It supports offline local music playback (MP3, FLAC, M4A, WAV) with automatic ID3 metadata and synchronized LRC lyrics, as well as online querying through NetEase via ChKSz. QQ Music, Kugou, and other sources are temporarily hidden and disabled. Existing favorites and backups are preserved; tracks from disabled sources are marked unavailable and excluded from playback. It provides local playlists, JSON backup, synchronized lyrics, and playback queues. The Mac app combines a menu bar library with a notch player; displays without a notch use a top capsule. Both surfaces share playback and library state.
The current iOS source features an artwork-led home, icon navigation, a floating mini-player, and a cover-tinted player with a glass control card. Circular glass controls and their original press feedback have been restored. The welcome sequence stages the cover, vinyl, and branding before entering the home; the full player slides up from the bottom, and track changes crossfade artwork and transition the background color. Lyrics, queue management, quality selection, and the in-place search overlay remain accessible. Search automatically refocuses once after the keyboard first appears, with no compatibility setting required, and protects marked-text composition from automatic searches. Third-party keyboards must be enabled in iOS Settings. The medium iOS Now Playing widget includes a shuffle button synchronized with the app. The screenshots were captured on the iPhone 17 Pro Simulator before the latest navigation and keyboard changes. These changes are included in the build 27 iOS preview IPA.
Public NetEase playlists can be imported from a share link or playlist ID, with a preview and deduplication before merging into the personal library. The native NetEase client provides artist and album browsing, lyrics, and direct playback; ChKSz provides song search and fallback services. Playback starts at master quality and falls back through Hi-Res, lossless, 320K, and 128K for the same song. The repository no longer ships any JavaScript/LX source scripts.
Source code is available under GPL-3.0, with separate notices for third-party code. Build both apps from Sonar.xcodeproj. GitHub Releases provides official pre-built macOS packages (SonarMac.dmg & SonarMac.zip) and an unsigned iOS preview IPA. The IPA requires your own signing and provisioning; the Mac build is ad-hoc signed and not notarized. Public packages contain no personal API credentials or private LX scripts. ChKSz services require your own key configured during a source build; the native NetEase client accepts your own login cookie in Settings. Public packages include neither credential. Music availability and playback quality depend on third-party services; playlist backups contain metadata, not audio.
两端均可从同一个 Xcode 工程构建。v1.0.0 正式发布 macOS 安装包(提供精致拖拽安装界面 DMG 与 ZIP)、SHA-256 校验值及本地音乐离线播放支持;iOS 未签名 IPA 见 v1.0.0-preview.5,App 与 Widget 均为 1.0 (27),包含输入法自动兼容与小组件随机播放。双端最新源码的变化见 更新记录。
Mac 安装包采用本地 ad-hoc 签名,没有 Developer ID 签名或 Apple 公证,首次打开可能被 macOS Gatekeeper 拦截。请先核对下载来源与校验值,首次打开若提示受限,按系统「隐私与安全性」提示允许,或在终端执行 xattr -cr /Applications/SonarMac.app 即可流畅运行。也可以按下方步骤直接打包或自行构建。
| 平台 | 系统要求 | 运行方式 |
|---|---|---|
| iPhone | iOS 17.0+ | 下载未签名 IPA 后自行签名,或在 Xcode 中选择 Sonar 并配置个人签名后安装 |
| Mac | macOS 14.0+ | 直接下载 SonarMac.dmg 拖入 Applications,或运行 ./scripts/package-mac.sh 一键打包 |
自行打包的 iOS App 可通过适用的个人签名工具安装。TrollStore 仅适用于其支持的系统与设备,请先核对兼容性。
项目提供了快速打包脚本 scripts/package-mac.sh,可一键生成 DMG 与 ZIP 产物:
./scripts/package-mac.sh产物保存在 build/SonarMac.dmg 与 build/SonarMac.zip。
因采用本地 ad-hoc 签名,若双击运行时遇到 macOS Gatekeeper 安全提示,可在终端运行解除限制:
xattr -cr /Applications/SonarMac.app- 从上述 iOS Release 下载
Sonar-1.0-build27-unsigned.ipa、同名.sha256和INSTALL-iOS.md。 - 在下载目录运行
shasum -a 256 -c Sonar-1.0-build27-unsigned.ipa.sha256,确认校验通过。 - 使用适用的个人签名工具签名 App 与内嵌 Widget,并按工具要求配置 Bundle ID、App Group 和描述文件,再安装到 iPhone。该 IPA 未签名,不能直接当作 App Store 安装包使用。
v1.0.0-preview.5 的公开 IPA 不含个人 API 凭据或网易云登录 Cookie。可在设置中配置自己的网易云 Cookie;ChKSz 功能需要通过构建环境变量配置自己的 Key 后重新构建。输入法兼容处理默认自动执行;第三方输入法须先在系统键盘设置中启用。自动兼容版本仍需在不同真机及签名工具组合下验证,第三方服务也可能影响在线功能。
需要一台 Mac、Xcode 与命令行工具,Xcode 应包含目标系统所需的 iOS / macOS SDK。音源实现为原生代码,无需 npm 或 JavaScript 音源打包;构建阶段生成凭据资源的脚本仍需要 Node.js 18+。无需本地 Agent 框架。
仓库已提供 Sonar.xcodeproj 与共享 Scheme。直接使用现有工程即可;仅在修改 project.yml 并重新生成工程时需要 XcodeGen。App 与 Widget 的构建版本应保持一致。
git clone https://github.com/can4hou6joeng4/Sonar.git
cd Sonar网易云在线功能由原生客户端实现(网易云直连接口 + ChKSz),仓库不再包含 JavaScript/LX 音源脚本,也不需要 Node 音源打包步骤。
打开 Sonar.xcodeproj,选择 Sonar Scheme 和 iPhone 模拟器,点击 Run(⌘R)。
安装到真机时,在 Xcode 的 TARGETS → Signing & Capabilities 中配置:
- 为 Sonar 和 SonarWidgetExtension 选择自己的 Team,启用自动管理签名。
- 为两者设置属于自己的唯一 Bundle Identifier,例如
com.example.sonar和com.example.sonar.widget。Widget 标识保持为 App 标识加.widget。 - 在两个 Target 的 App Groups 中启用同一个组,例如
group.com.example.sonar,替换默认的group.cn.bobochang.sonar。确认Sonar/Sonar.entitlements、SonarWidgetExtension/SonarWidgetExtension.entitlements与签名描述文件中的组一致。 - 连接并选择自己的 iPhone,点击 Run。
App Groups 的可用性取决于开发者账户及签名工具;免费账户或部分侧载工具可能不支持该能力。构建成功后,仍需确认 App、Widget、Bundle ID 和 App Group 都与所用签名匹配。
在同一工程中选择 SonarMac 和 My Mac,或运行:
./scripts/build-and-run.sh --verify脚本会生成 build/macOS/Build/Products/Debug/SonarMac.app,使用无需开发者证书的本地 ad-hoc 签名,并启动 App。可用 --debug 进入 LLDB、--logs 查看日志、--telemetry 查看播放切换事件。
本地 ad-hoc 签名适用于自行构建运行。面向其他用户分发时,Developer ID 签名与公证需要另行配置。
Mac 启动后显示状态栏图标及已启用的顶部播放器。点击状态栏图标打开选歌面板;播放列表、搜索、顶部播放器开关和歌单备份均在面板内。面板关闭后播放继续,退出按钮在面板右上角。无刘海屏幕使用顶部胶囊。
搜索支持歌曲、歌手、专辑与歌单四类,歌手与专辑可在面板内逐层浏览并直接播放;面板还提供歌词页、音质上限、播放倍速与定时关闭。冷启动会恢复上次曲目与进度,但保持暂停,由你决定是否继续。
点击歌曲旁的空心爱心加入个人歌单,再点实心爱心取消收藏。状态栏歌单、搜索结果、当前歌曲与顶部播放器的收藏状态会同步更新。
歌单与搜索结果保留正常滚动并隐藏滚动条,方便直接点击右侧爱心;歌曲行的播放和收藏操作都可直接完成。
取消收藏后,歌曲行会短暂显示“已移除”,再淡出收起;提示带上歌名,便于确认操作结果。
使用仓库脚本生成未签名 IPA;通过 Xcode 安装到真机的签名配置见运行 iOS App。
# 常规设备包,包含 Widget 扩展
./scripts/package-ios.sh --out=build/Sonar-local.ipa
# VPhone 验证包,移除 Widget 扩展
./scripts/package-ios.sh --no-widget --out=build/Sonar-vphone.ipa默认包含 Widget。--no-widget 用于规避当前 VPhone 环境观察到的 WidgetKit 扩展崩溃,该包不提供桌面小组件;常规设备使用包含 Widget 的版本。
两种产物均未签名,需使用个人签名工具签名后安装。包含 Widget 时,需同时处理 App 与扩展的签名,并保持 Bundle ID、App Group 与描述文件一致;具体安装方式以设备和工具的支持范围为准。若构建时注入了个人音源凭据,安装包也会包含这些值,请勿公开分发。
歌单与歌曲元数据保存在本机。iOS 设置中的「歌单备份」和 Mac 面板设置支持 JSON 导入、导出;导入会追加新歌曲并跳过重复项。两端资料库独立,可用备份手动迁移。
当前仅启用网易云音乐,不显示音源筛选控件。网易云直连层提供歌手、专辑、歌词、歌单详情与播放地址,ChKSz 提供歌曲搜索及部分回退服务;播放与收藏保留所选歌曲 ID。QQ、酷狗及其他音源的入口和网络调用暂时停用;已有收藏和备份完整保留,相关歌曲标记为「不可用」,无法播放或加入待播队列,仍可管理与备份。播放全部及随机播放会跳过停用音源,不会跨平台替换歌曲。
Mac 资料库位于 ~/Library/Application Support/cn.bobochang.sonar.mac/Sonar.store;启用 App Sandbox 签名时位于应用容器对应目录。资料库打开失败时保留原文件,并提供重试与原始资料导出。
公开源码不包含个人音源凭据,未配置凭据也可以构建并管理本地资料库。ChKSz 功能需要配置自己的 Key;网易云直连功能可在设置中保存自己的登录 Cookie(存入本机钥匙串),可用音质取决于账号权益与服务返回结果。公开包不内置登录态,也不提供会员权益。可通过构建环境变量配置:
| 变量 | 用途 |
|---|---|
SONAR_CHKSZ_KEY |
ChKSz 的网易云歌曲与歌单接口凭据 |
构建脚本生成 BuildCredentials.json 并打包到 App。该文件已被 Git 忽略;使用凭据应遵循相应服务的授权范围和使用条款。
播放解析与切歌
网易云使用 /api/163_search、/api/163_lyric、/api/163_music,并通过 /api/163_playlist 导入公开歌单。其他音源的请求在发出前被阻断,搜索失败时显示错误并支持重试。
ChKSz 默认从母带音质开始,网易云按 jymaster → hires → lossless → exhigh → standard 请求。更新到此策略时,原来的首选音质会迁移为最高优先;之后手动选择其他音质仍可调整起点。搜索结果中的音质标记不限制播放解析的尝试档位。
在 iOS 设置或 Mac 状态栏面板的设置中选择「从其他播放器导入」,粘贴网易云公开歌单分享链接或输入歌单 ID,使用 ChKSz 的 /api/163_playlist。QQ 歌单导入随音源暂时停用,酷狗歌单导入尚未提供。网易云普通长链接及通过 HTTP 跳转的官方短链接可用;无法识别的短链接可改用完整链接或 ID。
导入前显示歌单名称、来源和歌曲数量,预览不会写入资料库。确认后按「音源+歌曲 ID」去重并保留顺序,合并到个人歌单;不按歌名跨来源替换。一次最多读取 5,000 首;缺失或无效歌曲明确显示,部分结果需点击「导入已读取的歌曲」。服务失败或保存失败保留已有数据,未提供私密歌单登录或自动同步。
未返回可用链接、已知音质或歌曲权限错误、返回了低于请求档位的音质时,尝试下一档;媒体链接经 HTTPS 和有界探测验证后,按返回音质缓存。歌曲行的音质标记表示目录信息,与本次播放的实际音质可能不同。网络错误、凭据缺失和 HTTP 502/503 等服务错误会停止本次音质重试并显示明确提示,取消播放会中止请求。播放失败时不会自动改用其他音源或翻唱;仅启用网易云也不能保证第三方服务或所有曲目持续可用。参数以网易云文档为准。
iOS 与 Mac 会按当前播放模式提前解析并缓冲下一首。插歌、删歌、排序和模式切换会更新准备目标;iOS 收到曲终通知时立即申请后台切换时间,并以实际媒体时长补偿遗漏的通知。音源尚未就绪时仍需等待网络。Mac 的 --telemetry 记录解析、媒体就绪和开始播放的阶段耗时,不包含歌曲信息、播放地址或凭据,也不等同于音频输出设备的实测静音间隔。
ChKSz 单次请求默认在 8 秒内结束,媒体加载或缓冲持续等待 20 秒会刷新一次播放地址,再次超时则停止并支持手动重试。网络故障不会连续跳过其他歌曲;iOS 后台切换时间耗尽时也会结束等待。开启 Quantumult X 等 VPN 时沿用系统路由,若代理或 DNS 无法连接音源,会提示检查网络或 VPN 分流;应用无法保证不可达的代理线路恢复连通。
欢迎通过 GitHub Issues 反馈问题或建议。说明系统版本、触发步骤与实际表现;播放问题可附歌曲名称和来源,截图与日志请先移除凭据和个人信息。
请在阅读并理解以下条款后再使用或参与本项目:
- 项目目的与代码许可:Sonar 起源于个人兴趣和原生 iOS/macOS 架构实践。自有代码按 GPL-3.0 授权,使用、修改和再分发的权利与义务以许可证为准,包括许可证允许的商业使用;第三方代码遵循各自的许可。项目目的不构成额外的代码用途限制。
- 客户端与本地数据:本项目不运营音乐后端或音频托管服务,不随仓库或安装包分发受版权保护的音视频文件。歌单与歌曲元数据保存在本机;播放涉及的音频流、封面与歌词由客户端按用户操作向第三方服务请求。
- 知识产权归属:所有由音源返回的歌曲、歌词、专辑图文及商标等合法知识产权均归属于其各自的原始版权方、歌手、唱片公司或对应在线音乐服务平台。
- 服务与内容的使用:代码许可证不授予音乐内容、第三方服务接口或商标的使用权。使用者应遵守相应服务的授权范围、使用条款与所在地法律法规,尊重音乐版权,支持正版音乐服务。
- 侵权与异议处理:若任何版权方或个人认为本项目的开源代码对您的合法权益造成了影响,请通过 GitHub Issue 或电子邮件联系维护者,我们将第一时间积极配合下线或调整相关内容。
感谢 LINUX DO 为开发者提供分享作品、交流想法的空间,也感谢社区中愿意分享经验与开源实践的佬友。
- lx-music-mobile:早期版本的 JavaScript 音源适配曾参考其实现,相关脚本已在当前版本移除,历史来源保留在许可材料中。
- Atoll:Mac 顶部播放器的交互参考;Sonar 使用自己的窗口、界面与播放实现,未引入其源代码或素材。
- Spun 演示视频:iOS 大图主页、悬浮播放条与播放控制卡片的视觉参考,由 Sonar 使用 SwiftUI 实现。
第三方代码、依赖与许可说明见 THIRD_PARTY_NOTICES.md 和 LICENSES/。
Sonar 自有代码采用 GNU General Public License v3.0(GPL-3.0)。修改与再分发须遵循该许可证;第三方代码保留各自的许可与归属说明。



