[Ruby]网易云歌单批量下载

2,805 阅读4分钟

因为 Apple Music 在在国内的曲库比较匮乏,想把一些网易云上收藏的歌曲搬运到 Apple Music 上来,这样就不用来回切换 app 了。

那就来折腾一下吧 🤣

先看看 Apple Music 的歌曲都支持录入哪些信息

image

大概可以总结为以下几点

  • 歌名

  • 歌手名

  • 专辑

  • 发行年份

  • 专辑封面图

  • 歌词

然后去网易云网页端看看能不能抓到一些有用的信息,很快发现了这样一个接口

https://music.163.com/weapi/v6/playlist/detail?csrf_token=xxxxx

从接口路径可以大概猜出,它将返回一个歌单的详细信息,那里面肯定也包含我们关心的歌曲信息,查看 response 果然认证了猜想,其中 tracks 字段就是所有歌曲(省略了无用的字段)

{
...
    "tracks" : [
        {
            "name": "Mystery of Love",
            "id": 516358164,
            "ar": [
                {
                    "id": 42955,
                    "name": "Sufjan Stevens",
                }
            ],
            "alia": [
                "电影《请以你的名字呼唤我》插曲"
            ],
            "al": {
                "id": 36525952,
                "name": "Call Me By Your Name (Original Motion Picture Soundtrack)",
                "picUrl": "http://p3.music.126.net/Xz32BGhlEPPtirBZG1N4Ag==/18257390579783713.jpg",
            },
            "publishTime": 1509638400000
            }
    ]
...
}

现在我们相当于有了数据源,并且有了歌名、歌手名、专辑,接下来要做的就是遍历数据并下载,百度了一下,网易云的音频资源可以通过以下接口访问到

http://music.163.com/song/media/outer/url?id=#{id}.mp3

这个接口会返回 302 状态,并附带着一个临时的文件路径

HTTP/1.1 302
Server: nginx
Date: Sun, 20 Sep 2020 04:39:12 GMT
Content-Length: 0
Connection: keep-alive
Cache-Control: no-store
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Cache-Control: no-cache
MConfig-Bucket: 999999
Location: http://m801.music.126.net/20200920130412/62301086c7c7689000c1235a879516cc/jdymusic/obj/w5zDlMODwrDDiGjCn8Ky/2339973122/919f/5758/d006/2ec0f4621374e07a86c011a8a69e4658.mp3
X-Via: MusicServer
X-From-Src: 111.196.166.187

所以理论上,只要有了歌曲 ID ,我们就可以通过两次网络请求来下载到相应的音频文件。

当然,如果是 VIP 歌曲或已被下架的歌曲,通过这种方法是无法获取到的

封面图则不需要这么麻烦,直接从 picUrl 字段提供的 URL 下载即可。除此之外,歌词可以从如下接口请求到,入参也是只需要歌曲 ID

http://music.163.com/api/song/media?id=#{id}

返回值如下,lyric 字段即是 lrc 格式的歌词

{
    "songStatus":3,
    "lyricVersion":7,
    "lyric":"[by:Sherry_Esther]
[00:18.150]Oh, to see without my eyes
[00:21.960]The first time that you kissed me
[00:26.660]Boundless by the time I cried
[00:30.540]I built your walls around me
[00:35.450]White noise, what an awful sound
[00:39.930]Fumbling by Rogue River
[00:44.320]Feel my feet above the ground
[00:48.200]Hand of God, deliver me
[00:53.830]Oh, oh woe-oh-woah is me
[00:56.760]The first time that you touched me
[01:02.250]Oh, will wonders ever cease?
[01:06.610]Blessed be the mystery of love
[01:14.440]
[01:29.160]Lord, I no longer believe
[01:33.440]Drowned in living waters
[01:37.660]Cursed by the love that I received
[01:42.110]From my brother's daughter
[01:46.650]Like Hephaestion, who died
[01:50.990]Alexander's lover
[01:55.400]Now my riverbed has dried
[02:00.030]Shall I find no other?
[02:04.590]Oh, oh woe-oh-woah is me
[02:08.660]I'm running like a plover
[02:13.280]Now I'm prone to misery
[02:17.370]The birthmark on your shoulder reminds me
[02:27.770]
[02:49.220]How much sorrow can I take?
[02:53.170]Blackbird on my shoulder
[02:57.660]And what difference does it make
[03:02.160]When this love is over?
[03:06.490]Shall I sleep within your bed
[03:11.020]River of unhappiness
[03:15.420]Hold your hands upon my head
[03:19.900]Till I breathe my last breath
[03:24.490]Oh, oh woe-oh-woah is me
[03:28.650]The last time that you touched me
[03:33.220]Oh, will wonders ever cease?
[03:37.780]Blessed be the mystery of love
[03:47.110]",
    "code":200
}

但是因为 Apple Music 歌词滚动是基于 TTML 格式的歌词文件,而本地导入的歌词又只能以普通文本的形式导入,所以这里索性就处理成普通文本了,去掉了前面的时间戳信息。

发行年份可以从 publishTime 字段提供的时间戳算出。

至此,我们已经可以获取到歌曲的所有信息了,剩下的就是将以上操作脚本化,使用 Ruby 语言编写的脚本在这里:

GitHub - wgy6055/NeteaseCloudMusicDownloader: 下载网易云音乐歌单到本地

运行后可以看到所有歌曲资源都已被下载到本地

image

接下来手动导入到 Apple Music 中,同步到手机端播放的效果,除了歌词不能滚动,与其他歌曲并无太大区别,舒服了 😌

imageimage