缘起
网易云音乐的很多歌曲由于版权下架了,或者变成收费的,致使没法收听,所以须要一个小工具,但愿能够从其余来源补全歌曲。html
如图所示,不能听的显示为灰色。git
以前写的小工具XMusicDownloader(https://github.com/jadepeng/XMusicDownloader) 能够从多个来源搜索歌曲并下载,所以以这个为基础,能够很快实现需求。github
查看本文以前,建议查看开源工具软件XMusicDownloader——音乐下载神器.json
工具原理
- 获取用户歌单,找出无版权和收费歌曲
- 从QQ、咪咕、百度等源搜索这些歌曲,匹配成功的能够下载
- 下载后能够手动上传到云盘
获取用户歌单
借助NeteaseCloudMusicApi,能够方便调用云音乐的api。api
分析获取到的json,能够发现,包含noCopyrightRcmd
的是没有版权的,包含fee
的是收费的,咱们能够将这些歌曲提取出来,变为song对象。ide
private static List<Song> FetchNoCopyrightSongs(JObject json) { List<Song> noCopyrightsSongs = new List<Song>(); foreach (JObject songObj in json["songs"]) { int id = 0; if (songObj["noCopyrightRcmd"].HasValues || songObj["fee"].Value<int>() == 1) { noCopyrightsSongs.Add(NeteaseProvider.extractSong(ref id, songObj)); } } return noCopyrightsSongs; } public static Song extractSong(ref int index, JToken songItem) { var song = new Song { id = (string)songItem["id"], name = (string)songItem["name"], album = (string)songItem["al"]["name"], //rate = 128, index = index++, //size = (double)songItem["FileSize"], source = "网易", duration = (double)songItem["dt"] / 1000 }; song.singer = ""; foreach (var ar in songItem["ar"]) { song.singer += ar["name"] + " "; } if (songItem.Contains("privilege") && songItem["privilege"].HasValues) { song.rate = ((int)songItem["privilege"]["fl"]) / 1000; var fl = (int)songItem["privilege"]["fl"]; if (songItem["h"] != null && fl >= 320000) { song.size = (double)songItem["h"]["size"]; } else if (songItem["m"] != null && fl >= 192000) { song.size = (double)songItem["m"]["size"]; } else if (songItem["l"] != null) { song.size = (double)songItem["l"]["size"]; } } else { song.rate = 128; song.size = 0; } return song; }
从其余来源获取歌曲
在以前的博文开源工具软件XMusicDownloader——音乐下载神器里,咱们有一个聚合的搜索歌曲的方法:工具
public List<MergedSong> SearchSongs(string keyword, int page, int pageSize) { var songs = new List<Song>(); Providers.AsParallel().ForAll(provider => { var currentSongs = provider.SearchSongs(keyword, page, pageSize); songs.AddRange(currentSongs); }); // merge return songs.GroupBy(s => s.getMergedKey()).Select(g => new MergedSong(g.ToList())).OrderByDescending(s => s.score).ToList(); }
相似的,匹配也是先搜索,可是要排除网易源,而后根据搜索结果去匹配。搜索的时候,能够将 “歌曲名称 + 歌手名称” 组合用来搜索。url
public MergedSong SearchSong(string singer, string songName, string exceptProvider) { // search var songs = new List<Song>(); Providers.AsParallel().ForAll(provider => { try { if (provider.Name != exceptProvider) { var currentSongs = provider.SearchSongs(singer + " " + songName, 1, 10); songs.AddRange(currentSongs); } } catch (Exception e) { } }); // merge List<MergedSong> mergedSongs = songs.GroupBy(s => s.getMergedKey()).Select(g => new MergedSong(g.ToList())).OrderByDescending(s => s.score).ToList(); // match foreach (MergedSong song in mergedSongs) { if (song.singer == singer && song.name == songName) { return song; } } return null; }
软件界面
软件界面,增长用户、密码输入spa
搜索结果,设置为默认选中:.net
List<ListViewItem> listViewItems = new List<ListViewItem>(); mergedSongs.ForEach(item => { ListViewItem lvi = new ListViewItem(); lvi.Text = item.name; lvi.SubItems.Add(item.singer); lvi.SubItems.Add(item.rate + "kb"); lvi.SubItems.Add((item.size / (1024 * 1024)).ToString("F2") + "MB"); //将文件大小装换成MB的单位 TimeSpan ts = new TimeSpan(0, 0, (int)item.duration); //把秒数换算成分钟数 lvi.SubItems.Add(ts.Minutes + ":" + ts.Seconds.ToString("00")); lvi.SubItems.Add(item.source); lvi.Tag = item; lvi.Checked = true; // 默认选中 listViewItems.Add(lvi); });
搜索出来后,下载能够彻底复用以前逻辑。
下载歌曲使用
下载后的歌曲,能够经过网易云音乐客户端,上传到云盘,而后批量选中,添加到我喜欢的音乐
批量选中后收藏到歌单:
工具下载地址
-
能够从github下载
https://github.com/jadepeng/music163tool -
国内gitee地址:
https://gitee.com/jadepeng/music163tool
做者:Jadepeng
出处:jqpeng的技术记事本--http://www.cnblogs.com/xiaoqi 您的支持是对博主最大的鼓励,感谢您的认真阅读。 本文版权归做者全部,欢迎转载,但未经做者赞成必须保留此段声明,且在文章页面明显位置给出原文链接,不然保留追究法律责任的权利。