緣起
網易雲音樂的很多歌曲由於版權下架了,或者變成收費的,致使沒法收聽,所以須要一個小工具,但願能夠從其餘來源補全歌曲。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 您的支持是對博主最大的鼓勵,感謝您的認真閱讀。 本文版權歸做者全部,歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接,不然保留追究法律責任的權利。