惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

AI
AI
S
Schneier on Security
T
Tenable Blog
A
Arctic Wolf
I
Intezer
博客园 - 司徒正美
A
About on SuperTechFans
The Hacker News
The Hacker News
H
Hacker News: Front Page
Security Archives - TechRepublic
Security Archives - TechRepublic
Attack and Defense Labs
Attack and Defense Labs
Webroot Blog
Webroot Blog
T
The Blog of Author Tim Ferriss
Know Your Adversary
Know Your Adversary
L
Lohrmann on Cybersecurity
D
Docker
T
The Exploit Database - CXSecurity.com
博客园_首页
Microsoft Azure Blog
Microsoft Azure Blog
N
Netflix TechBlog - Medium
H
Help Net Security
Hacker News: Ask HN
Hacker News: Ask HN
Recorded Future
Recorded Future
P
Proofpoint News Feed
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Help Net Security
Help Net Security
L
LINUX DO - 最新话题
AWS News Blog
AWS News Blog
量子位
MyScale Blog
MyScale Blog
博客园 - 聂微东
S
Security @ Cisco Blogs
The Register - Security
The Register - Security
www.infosecurity-magazine.com
www.infosecurity-magazine.com
月光博客
月光博客
V2EX - 技术
V2EX - 技术
T
Troy Hunt's Blog
SecWiki News
SecWiki News
L
LangChain Blog
B
Blog
博客园 - 三生石上(FineUI控件)
Cyberwarzone
Cyberwarzone
H
Heimdal Security Blog
Scott Helme
Scott Helme
O
OpenAI News
B
Blog RSS Feed
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
M
MIT News - Artificial intelligence
Google DeepMind News
Google DeepMind News
雷峰网
雷峰网

分享创造

[发 15 个码] 开发的 Mac 应用 分享 KCase 脑图测试用例生成平台(AI 辅助生成测试用例) 标签页囤积症自救:写了个插件 TabRack,主打快速检索、自动分类和 AI 摘要 [file-preview]一个比较全面的在线文件预览组件库-支持 react 和 vue 撸了 iOS 个[极简水印相机],直接免费 做了一个 V2EX Skill 写了个 iOS 打码 App「遮鸭 Maskduck」,纯离线免费 35 岁前端,裁员失业后,我花 1 个月做了个 AI 生图网站 亲身经历猫咪急症,我做了一款猫狗疼痛检测工具,希望能救你家毛孩一命 如何用 AI 做比较酷炫的落地页? 求真!最近 AI 生图的能力强到可怕 开源一个查看 k8s 的菜单栏工具-kubebar Packpour:我做了个专门给 App Store Connect 填多语言元数据的小工具 面对 140 年一遇的超级厄尔尼诺,我做了个全球监测小站 做了一个自动翻译的 Hacker News 客户端 做了一个 AI 头像生成器,可以免费生成 2 次 [送码 50 个] 自己手搓了个高颜值的倒数日 App——拾光机,求 V 友们指点 一个将苹果健康 APP 数据导出的工具,然后把你的数据喂给 AI 分析 我做了一个叫「订阅斩」的 iOS App,专门对付那些悄悄扣钱的订阅 做了个草率的日麻互动漫画,听听反馈 喜欢自己洗车的朋友们,我用 ai 做了一款洗车小程序 -- 洗车志 感谢 V2EX 上各位 NAS🍆 和 Datahoarder 玩家的关注和真实反馈!作为个人开发者,能得到这么多硬核玩家们的讨论,我非常荣幸。 用 AI 开发熊孩子自律的小程序 用 OpenClaw 搭建个人运动助手 今天摸鱼给 NanaAI 也接入了 GPT-Image-2 [Video Companion]一个 chrome 插件,解决大多对视频操作的需求~欢迎使用提 bug AI 时代,做产品简单了,把产品推广出去却变的更难了~ bestskills.dev - Skills 精选和评测站点 免 ROOT 强力卸载安卓广告软件 一个 All In One 的运维工具,支持 SSH、数据库、Redis 管理 [开源] Codeg V0.10:专注于代码生成的多智能体 IDE(cc、codex、gemini、opencode……),新版本重构了工作区,飞一般的体验,支持桌面端、服务器部署 老婆嫌鼻型不完美?我做个医美 AI,帮你一键分析变美效果! BrandMaker-3 分钟帮你搞定品牌资产设计 [开源·Actionow] 包含 Agent 辅助·团队协作·多租户·积分系统的 AI 影视创作 SaaS 平台 OCR 发票识别服务 编程小白用 Nextjs Saas 搭建的第一个 GPT Image 2 体验站 希声 (Still) :为 Audiobookshelf 打造的 iOS 原生客户端 Opus 真的牛炸了! 5 天和比 Mermaid 更专业的图表渲染引擎 最近在做一个 OPC 社区,欢迎大家注册。 做了一个内网/本机用的 todo 系统(rbtodo) 昨天上线一个推理密码的小游戏,大家有空玩玩。 自己做的 GPT Image 2 生图网站 可白嫖 Codex 设计的垃圾小游戏,玩完想吐 写了一个 NestJS 中文文档站 分享一个刚上线就挂的网站:蹭词需注意啊 深夜开源 OpenVibble,不需要开发板也可蓝牙连接 Claude Desktop 和 CC 监工了! Rust 写的 ML 驱动的本地漫画翻译器,一键汉化本子! 用 AI 帮助写简历和准备面试,给大家推荐这个我们开发的使用求职助手网站 给猫梳毛小游戏 Claude Code 小白免费从入门到精通,系列视频教程,第一期 一个把单词、句子、阅读、复习全打通的英语学习小程序 - “匠心英语学习助手” 年前说要把 macOS 的文件备份应用 savepoint 开源的,但是耽误了一阵子 做了个开源的 AI 代码安全智能体 mythos-agent,想在 V 站求轻拍 一个小项目:快速清理磁盘大文件的 Python 代码 我用 Agent 写了个 NFL(美国国家橄榄球联盟)随机生成器 & 抽签转盘 Basevolt: 我做了一个本地优先的数据库管理工具,一分钟生成管理后台 vibe 了一款记忆训练游戏 iOS 照片备份 App「🍉西瓜备份」上线,直接免费 我也来分享一个小游戏《勇闯霍尔木兹海峡》 solo 做了个 AI 图片转视频的工具站,来 V 站交个作业 大家好,我们的出海 GEO 平台 - Dageno AI,今天正式在 Product Hunt 上线了,诚邀大家来支持我们一票! 一个自动化工具,操作浏览器,常用功能支持 hub, LLM 友好 写了个双人爱之语测试网站,帮我和对象解决了多年的矛盾 开发了一个 patches 风格的数字矩形游戏,欢迎来挑战 BoringTun 不做 manager,那我用 Rust 做一个: WG-FRIEND PushGo,全新消息推送 App,开源免费,支持 iOS / watchOS / macOS / Android 做了一个 Typeless 平替,便宜 10 倍,用 Claude Code / Agent 时再也不用憋着慢慢打字了 一个 MacOS 右键新建文件的拓展应用,我知道本站大佬应该用不上😄 个人开发了 3 年的数据可视化工具发布桌面端了 产品派新版发布了,增加通知偏好邮件通知功能,修复发布产品网址的问题 我们把给不同产品单独写的 AI 客服,做成了一个通用产品 什么样的独立开发产品真的能赚到钱? GridMove for macOS:按窗口任意地方移动窗口,或者快速调整为自定义布局 写了个小工具,试图把 Everything 的体验带到 Mac 上 不只是 NAS:走出局域网, Nas Player Pro 依然能打 做了一个极简的分析澳门博彩游戏胜率和数学期望的网站,希望能对有这方面兴趣的兄弟们有点用 「开源」SONIC-LENS / MUSIC ARCHIVE / MAC + iPhone + iPad [开源] Vela — 一款本地优先、隐私安全的 AI 长文/小说创作 IDE gpt image 2 貌似全量上线了,捡漏了一个不错的域名,再试一次 分享几个效率小工具,在 Finder 中一键使用 claude code / codex-cli / opencode-cli / gemini-cli 打开项目 好消息,貌似我的开源项目被盗版,发布到了微软商店 # [拉票] 我用 TRAE SOLO 做了个 macOS App「到站请下车」(求支持) 越来越勤劳了,做了一个交易的小产品,即将上线…… 大功能更新再发一次:订小阅 - 小程序管理你的订阅 写了一个 skills,用于判断某些产品是否是智商税 打磨了一款远程 vibe 工具 给大家介绍一下我的第六个想法:免安装的 mac 磁盘空间清理利器 mac-space-cleanup skill 做了个剪贴板&截图增强工具 养小龙虾的朋友们快来测 agent 的 mbti🤖 任何一个 agent 都可以一键参与测试 如果你做过 segmentation,可能默认用了太久 argmax 跟风复刻了个 Web Harmonium,有点意思 分享下自己 vibecoding 的 android ssh 软件,基于 connectbot + frp 来实现 尝试用 claude code 做了一个完整的 saas 订阅站 PasteMemo v1.5.0:接力模式大重构,自动化接入 macOS 快捷指令 开源复刻 CodeX Computer Use 的「权限申请」交互,目前没看到比这个更细致的 做了个 Claude Code 多账号切换启动器,不用再反复 /login 了 code is cheap, show me your design ——分享一个我的 AI 时代的软件开发范式 折腾了个自托管 Docker Registry —— 一个镜像跑起来就是完整的(UI + 账户 + 权限) 用时一个月,开发了一款适合上班摸鱼的 web 端 Roguelike RPG 游戏 用 JS+HTML+CSS 做了一款网页版宝可梦游戏
用 golang 写了,一套面向个人音乐资产的本地优先音乐系统
vincentchyu · 2026-04-23 · via 分享创造

SonicLens:一套面向个人音乐资产的本地优先音乐系统

很多开发者都做过“记录自己在听什么”的小工具,但真正把这件事做成一个可以长期运行、可持续扩展、还能支撑多端体验的完整工程,其实并不容易。

我做 SonicLens,并不是为了再造一个播放器,也不是为了做一个简单的 scrobble 脚本,而是想回答一个更具体的问题:

如果一个人多年分散在 Apple Music 、Roon 、Audirvana 、Last.fm 里的听歌行为,最终都要沉淀为属于自己的音乐资产,那么这套系统应该长什么样?

项目: https://github.com/vincentchyu/sonic-lens.git

这就是 SonicLens 的起点。

它的目标很明确:

  • 统一接入多个播放来源,持续监听和记录播放行为
  • 把听歌历史沉淀到本地可控的数据模型中,而不是依赖单一平台
  • 在此基础上构建统计、资料库、歌词、AI 解析、收藏同步和多端浏览能力
  • 让这些能力不只是“能跑”,而是能成为一个长期维护的产品

如果用一句话概括这个项目,我会这样描述:

SonicLens 是一套以“个人音乐资产”为中心构建的本地优先音乐基础设施,它把听歌记录、资料整理、AI 洞察和多端消费体验连接成一个完整闭环。

SonicLens Web

一、这个项目真正想解决的,不是“听了什么”,而是“如何拥有自己的音乐历史”

大多数音乐平台都能告诉你“最近听了什么”,但它们很少真正为用户提供一套稳定、可迁移、可扩展的数据资产模型。

一旦平台策略变化、账号迁移、播放器更换,过去的听歌行为往往就会被切碎,最终只剩一堆零散记录。对我来说,这件事最大的问题不是统计缺失,而是:

你的听歌历史没有真正属于你。

SonicLens 的设计从一开始就不是围绕某个单独播放器展开,而是围绕“个人音乐资产沉淀”展开。也正因为如此,它在架构上天然不是一个脚本型项目,而更像一个围绕领域模型搭建的系统:

  • 后端长期运行,负责监听、同步、聚合、广播和任务调度
  • Web 管理端负责运维入口、数据看板和后台治理
  • soniclens-bridge 负责 macOS 、iPadOS 、iPhone 三端原生消费体验
  • AI 解析、歌词、收藏状态、资料库同步都围绕统一的数据事实源工作

这意味着它的工程重点不在“把接口调通”,而在于让多个异步链路、多个数据来源和多个客户端之间保持一致性。

二、从工程视角看,SonicLens 其实是四层系统

从当前仓库实现看,SonicLens 可以拆成四个核心层次。

1. 持续运行的 Go 后端

后端入口在 main.go。应用启动后会初始化配置、日志、OpenTelemetry 、Redis 、数据库、MusicBrainz 、对象存储,然后启动:

  • HTTP API 服务
  • WebSocket 实时推送
  • 播放器监听链路
  • Dashboard 统计调度
  • D1 云侧镜像同步
  • 播放记录 replay 补偿任务
  • Bonjour 局域网发现广播

这类启动方式的重点,是把系统当作一个长期运行的服务,而不是一组临时执行的命令。

2. 明确分层的业务结构

这个项目后端不是把所有逻辑塞进 handler ,而是做了比较清晰的职责分层:

  • api/ 负责 Gin 路由、参数绑定、缓存中间件和响应
  • internal/logic/ 负责业务编排,例如资料库、音眸、流派、MusicBrainz 、封面等服务
  • internal/model/ 负责所有数据库 CRUD 和事务入口
  • internal/scrobbler/ 负责播放器监听与当前播放状态处理
  • internal/sync/ 负责后台同步、D1 镜像和调度任务
  • core/ 负责 Redis 、Telemetry 、对象存储、AI 、歌词、WebSocket 、Bonjour 等基础能力

这种结构的价值不是“看起来规范”,而是当项目开始变复杂之后,数据访问边界、事务边界和业务边界依然可控。

GEMINI.md 里对这一点有非常明确的约束:数据库 CRUD 必须收口在 internal/model/,Logic 层只负责编排,不允许把原始 SQL 和 GORM 细节散落到业务代码里。

这是一个非常重要的工程判断,因为它直接决定了系统后期是否还能继续演化。

3. 产品化的原生三端客户端

很多个人项目做到后端和网页就结束了,但 SonicLens 还继续往前走了一层:我为它单独做了一套原生 Bridge 客户端。

soniclens-bridge 目前包含四个 target:

  • SoniclensBridgeMac
  • SoniclensBridgePad
  • SoniclensBridgePhone
  • SoniclensActivities

也就是说,这不是一个“顺带做了个移动端壳”的项目,而是一套有明确模块边界的多端产品:

  • 共享层 SoniclensCore 负责网络、模型、资料库同步、连接恢复、WebSocket 、播放态与收藏态
  • ViewModels 负责各类业务页的数据协调
  • Views 层根据 macOS 、iPadOS 、iPhone 形态做容器和交互差异
  • iPhone 侧还包含 Live Activity 和分享海报相关能力

project.yml 可以看到,整个 Xcode 工程本身也是生成式管理的,target 、scheme 和 extension 嵌入关系统一由配置驱动,而不是手工在 .xcodeproj 里维护。这一点在多人协作和长期迭代时非常关键。

SonicLens iPhone

4. 以 AI 为能力层,而不是以 AI 为项目本体

SonicLens 里我最看重的一点,是 AI 在这里是增强层,不是伪需求的中心

项目里的“音眸”能力并不是简单给歌曲丢一个 prompt ,而是围绕真实业务对象构建的:

  • 曲目 insight 有独立 schema 、版本、评分和反馈
  • 专辑 insight 不是重复逐曲分析,而是聚合曲目 insight 之后再进行二次生成
  • 解析结果支持历史版本、推荐版本和反馈回灌
  • 长耗时任务通过 insight_job 做异步调度,并用 WebSocket 推送状态
  • LLM 调用日志被单独记录到 llm_call_logs,用于审计、回放和排障

这意味着 AI 不是一个“调用成功就结束”的黑盒,而是被纳入了工程系统本身。

三、这个项目最有技术含量的部分,不是接口数量,而是几个闭环

如果只看 API 数量,SonicLens 当前已经有几十个接口;但真正体现专业性的,不是接口多,而是几个关键闭环是否成立。

1. 播放监听闭环:从播放器状态到统一播放事实

SonicLens 当前支持接入 Apple Music 、Audirvana 、Roon 等来源。播放器监听不是单纯轮询标题字符串,而是围绕统一的播放事实在工作:

  • 识别当前播放器运行状态和播放状态
  • 读取歌曲元信息,包括曲目号、盘号、专辑副标题、采样率等细节
  • 生成统一 TrackMetadata
  • 判断播放阈值,决定何时落库、何时 scrobble
  • 推送 WebSocket now_playing
  • 同步收藏态并维护 favorite projection

这部分实现里还有几个我自己非常在意的细节:

  • Apple Music 元数据不是一视同仁处理,而是根据来源质量给出不同置信度
  • 当前播放链路有独立 trace 设计,不会每次轮询都制造噪声 span
  • 停止播放时会判断是否还有其他播放器处于活跃状态,避免误广播 stop

这些处理看起来不“炫技”,但恰恰决定了系统在长期运行时是不是稳定。

2. 资料库同步闭环:不是简单拉接口,而是本地索引系统

SonicLens 的客户端资料库不是“每次打开页面重新请求远端分页”这种常见方案,而是采用了一套更像本地应用的设计:

  • 服务端通过 library_change_log 记录专辑和曲目的增删改
  • /api/library/sync 提供基于版本号的增量同步
  • WebSocket 广播 library_updated(version) 作为刷新触发器
  • Bridge 客户端本地维护 SQLite 轻量索引和 FTS5 搜索
  • LibrarySyncService 先尝试增量 apply ,失败后自动回退全量重建

这套设计有两个明显好处。

第一,列表浏览和搜索体验不会严重依赖网络往返,客户端更接近原生 app 的使用感受。

第二,服务端和客户端之间的边界非常清楚:服务端提供变更事实,客户端维护查询性能。

这也是为什么 GEMINI.md 里会专门把“本地 SQLite 轻量索引 + FTS5 + 增量同步 + WebSocket 推送 + 详情页懒加载”列为长期红线。因为这不是一个实现细节,而是整个三端体验成立的基础。

3. 音眸异步任务闭环:把 AI 长任务做成产品能力

很多项目接入 AI 时最容易忽略的一点,是长耗时任务的状态管理。

SonicLens 里我专门为 AI 解析设计了 insight_job 这条链路,用它承载:

  • 任务创建
  • 幂等复用
  • 运行中状态
  • 终态结果
  • 失败原因
  • 客户端恢复
  • Live Activity 联动

对应的接口链路也很完整:

  • POST /api/insight-jobs 创建任务
  • GET /api/insight-jobs/:id 查询任务和调用流水
  • POST /api/insight-jobs/:id/cancel 取消任务
  • POST /api/insight-jobs/:id/retry 重试任务
  • WebSocket insight_job_updated 广播状态变化

这背后体现的是一个产品判断:

AI 解析不是“点一下等结果”,而是要适配真实客户端环境,包括前后台切换、网络中断、长耗时等待和终态回流。

如果未来我把这个项目继续做大,这条链路依然能继续承载更复杂的模型能力,而不是推倒重来。

4. 数据治理闭环:系统不是只会“记”,还要会“修”

这是我很喜欢 SonicLens 的一个点。

音乐数据不是天然干净的。专辑名不一致、版本名混杂、曲目归属错误、第三方元信息缺失,这些问题只要你真的做过音乐资料系统,就一定会遇到。

所以我没有把系统停留在“记录下来”,而是继续做了治理侧能力:

  • Pending Albums 待归因工作台
  • MusicBrainz 候选搜索与绑定
  • Deep maintenance 深度维护
  • Replay 播放记录补偿
  • 收藏状态补写

这意味着 SonicLens 不是一个被动收集器,而是一个可以持续整理自己数据的系统。

对我来说,这类能力的价值非常高,因为它说明项目已经开始从“功能实现”走向“数据运营”。

四、我在这个项目里特别重视的工程质量点

如果把 SonicLens 当成一份作品来看,我最希望别人看到的不是“功能很多”,而是我对工程质量的判断标准。

1. 不是只写功能,而是写长期可维护的结构

GEMINI.md 里保留了大量长期架构约束,这件事本身就说明这个项目不是靠短期记忆在推进,而是在持续沉淀工程规则。

例如:

  • DAO 必须收口,事务入口必须由 internal/model/ 提供
  • 异步逻辑不允许直接写裸 go func,必须走安全封装
  • OpenTelemetry 、Redis 、GORM 、database/sql 的观测链路要统一
  • API 变更要同步维护文档
  • 客户端 target 变更必须先改 project.yml

这些约束看起来“麻烦”,但正是这些约束让系统不会在迭代三个月后失控。

2. 对可观测性有明确投入

这个项目不是出了问题靠猜。

从实现上看,Telemetry 已经接入到:

  • Gin 入站链路
  • Redis
  • GORM
  • D1 database/sql
  • 出站 HTTP client

而且不仅有 trace ,还有 meter 、db stats metrics 和启动自检逻辑。这对一个个人项目来说其实投入不小,但我认为非常值得,因为系统一旦有多个后台任务、多个外部依赖和多条异步链路,没有观测能力几乎不可能稳定演进。

3. 对客户端性能边界有明确设计

在三端客户端这块,我没有把所有状态都堆进一个全局 store ,而是明确区分了:

  • AppStore 负责低频全局状态
  • PlaybackStore 负责高频播放态
  • FavoriteStore 负责收藏态
  • LibraryViewModel 做 single-flight 、页优先加载和过期请求丢弃

这一套拆分说明我在做的不是“能显示出来就行”的 SwiftUI 页面,而是在认真处理高频状态更新对列表、详情和播放条的影响范围。

4. 把文档当成系统的一部分

SonicLens 不是写完代码才补 README 的项目。

除了 README ,本仓库还维护了:

  • GEMINI.md 作为长期架构记忆
  • api/api.md 作为接口盘点
  • Bridge 客户端边界清单
  • 按日期归档的 memory 清单

我越来越认同一件事:真正复杂的个人项目,必须有自己的“工程记忆系统”。

因为当系统开始跨越后端、客户端、异步任务、数据同步和 AI 能力时,光靠代码本身已经不足以承载完整上下文。

五、为什么我觉得 SonicLens 是一份值得拿出来展示的作品

如果从面试或者技术交流的角度看,我认为 SonicLens 最有说服力的地方,不是它“用了多少技术栈”,而是它体现了一种完整的工程能力组合。

它至少覆盖了下面这些维度:

  • Go 后端分层架构设计
  • 长期运行服务的任务调度与资源治理
  • WebSocket 实时推送与状态同步
  • 本地优先的数据建模与资料库增量同步
  • 多端原生客户端的共享层设计
  • AI 能力的工程化接入,而不是 demo 式接入
  • 数据治理与外部元信息修复链路
  • 可观测性、文档化和长期演化约束

更重要的是,这些能力不是彼此孤立的,而是组成了一个完整系统。

换句话说,SonicLens 不是“我会做后端”“我也会写一点 SwiftUI”“我还能接个大模型”的拼盘式展示,而是一份能体现系统设计意识、产品意识和工程落地能力的综合作品。

六、接下来它还会继续往前走

SonicLens 现在已经不是一个原型,但我也不把它视作完成态。

接下来我仍然会继续打磨几个方向:

  • 更稳的资料治理和专辑归因能力
  • 更完整的 AI 反馈回灌与质量优化
  • 更成熟的分享和输出链路
  • 更统一的多端体验细节
  • 更长期可维护的系统观测与运维工具

对我来说,做 SonicLens 的意义从来不只是“做一个能用的项目”。

它更像是一块长期打磨的工程试验田:我把自己对后端架构、客户端设计、数据治理、AI 工程化和产品实现的理解,都持续沉淀在这里。

如果未来有人问我,什么项目最能代表我真正的技术表达,我想 SonicLens 一定会是其中之一。


如果你也对“个人音乐资产”“本地优先产品”或者“AI 与传统软件系统的结合方式”感兴趣,欢迎交流。

对我来说,SonicLens 不是结束,而是一个还会继续生长的开始。