未命名

说来惭愧、作为一名音乐爱好者,一直也没怎么开发过和音乐相关的小工具。不过最近总算是做了点跟音乐相关的小东西了。

歌单导出

国庆节前某天,无意中扫了一眼网易云上的收藏曲目数满2000首了,加上之前虾米上的加起来也快有1W首了,突然特别想按艺术家统计下,谁才是我收藏曲目数最多的!

可惜网易云网页上只能看最多1000首,虾米我拿出了几年前当时某朋友要迁移到网易云我写的js小脚本,没想到还能正常运行、很激动的等着执行完。但在3000首的时候没法继续玩下翻页了!

image-20201106222504694

网上搜了一圈,直到看到有朋友说网易云PC客户端会缓存一份歌单数据在本地数据库中,顺着路径找了下果然有一个SQLite数据文件,确实有相关的数据。立马写好了解析脚本顺带把虾米音乐(本地也有缓存)也一起兼容了。

想着大众说不定也是需要这么个工具,刚好也一直想找机会实践下Electron,三下五除二套了个UI在节前在放到网络上去了。

image-20201106231940755

zaza果然是我最爱的哈哈哈哈,接着steve howe,yes和dream theater!

没想到还真有人用,有个朋友表示很好很实用顺带提了两个需求

  • 不只是默认收藏的歌单导出
  • 导出m3u8以便导入到其它听歌的设备

另一个朋友则是遇到了BUG,明明安装了网易云音乐客户端,但是无法识别到本地数据库文件。几番排查,是因为我故作聪明的没有拿系统默认的用户目录(homedir)而是拿用户名自己拼了个文件路径。用户名和用户目录如果命名不一样,那么肯定就无法定位到文件了。

last.fm

一直久仰last.fm的大名,在做歌单导出的时候也想着如果能记录下平时的听歌数据,那么应该就能很好的理解自己的兴趣,利用这些数据推荐可能感兴趣的音乐给我。

image-20201106222841278

国庆节回来试着把导出的1w首歌曲条目导入到了last.fm,准备感受一下他们的推荐引擎效果如何,用下来大概有几个问题:

  • 推荐的列表里夹杂着我早期的听歌风格
  • 听过的重复推荐
  • 推荐内容更新频次太低、几乎是固定的列表

可以说是很失望,一方面他们的数据metadata确实很丰富,我听的大部分音乐在上面都能找到详细的数据,而且都有不错的收听数据,标签分类也确实很丰富。

不过某天在上面查我最近很爱的一张专辑的时候,试着听了下底部的相似专辑!结果惊呆了,很合口味!!

image-20201106223032427

专辑推荐

于是便有了个想法,或许可以利用近期收藏歌曲列表得到最近感兴趣的专辑列表 + 遍历后基于此得到每日推荐专辑列表,加上核心需求听过的去重,想想还有点小激动,因为这样基本上不用再面对歌荒了哈哈哈,这是我迫切需要的!此外数据源上我把豆瓣音乐下面的相似专辑也纳入进来了(豆瓣api直接能用、可见以前多开放)

考虑到无成本能让项目更好的长存下去,为了充分发挥客户端计算的力量,我选择了做成纯客户端的项目。开始想做成网页端这样更新方便,因为CORS的缘故和要获取近期的收藏列表,但是这个可以额外引入Chrome插件来提供跨站内容抓取能力。

image-20201106224457058

直到后续有朋友说只用Safari怎么办,想着干脆直接集成到Electron里去得了,集成也是很方便的,直接加载线上网页,把Chrome插件提供的能力在该环境兼容了一遍,获取近期歌单直接用本地内容库来做,后续去重也方便。

但是忽略了一个核心问题就是last.fm在国内访问正常网络是很慢的,动辄15s的速度,如果要遍历的专辑数量多一点,速度实在是不能忍。只好在阿里云香港部署了个函数计算来做抓取请求的中转,这样速度降到了2s以内。

于是近期每天听歌基本上就不愁听什么了,每天就是打开看看挑两三张听,还真又发现了很多优秀的音乐。

当然目前推荐的缺点也很明显,以近期听过的歌很容易导致同质化的推荐,需要引入其他机制来增加一些广度的内容,这样可能会有更多意想不到的内容进来,但是不管怎么样,最终还是人自己来选择用什么策略找,选择听什么这才是我想要的。

音乐播放能力

本身也只想做个找歌的工具,对于能不能播放其实我是无所谓的、不过也试着做了下,技术上还是蛮好玩的。我没有采用盗链的方式来获得播放能力,而是通过window.open新开网易云的网页,然后需要chrome插件(Electron里做也很方便),注入js执行能力到网易云的网页上,父级通过postMessage外部传递代码到内部执行,构建了一个代理层,和window.openner通讯把iframe内部的播放状态告知给外层,然后也提供了一些播放器控制的能力给外层,这样就能做到仅window.open的方式来获得播放能力。

最后附上下载链接:

https://music.wechatsync.com/