網易雲音樂無版權音樂補全工具
- 2020 年 8 月 25 日
- 筆記
- ASP.NET編程, XMusicDownloader
緣起
網易雲音樂的不少歌曲因為版權下架了,或者變成收費的,導致無法收聽,因此需要一個小工具,希望可以從其他來源補全歌曲。
如圖所示,不能聽的顯示為灰色。
之前寫的小工具XMusicDownloader(//github.com/jadepeng/XMusicDownloader) 可以從多個來源搜索歌曲並下載,因此以這個為基礎,可以很快實現需求。
查看本文之前,建議查看開源工具軟體XMusicDownloader——音樂下載神器.
工具原理
- 獲取用戶歌單,找出無版權和收費歌曲
- 從QQ、咪咕、百度等源搜索這些歌曲,匹配成功的可以下載
- 下載後可以手動上傳到雲盤
獲取用戶歌單
藉助NeteaseCloudMusicApi,可以方便調用雲音樂的api。
分析獲取到的json,可以發現,包含noCopyrightRcmd
的是沒有版權的,包含fee
的是收費的,我們可以將這些歌曲提取出來,變為song對象。
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();
}
類似的,匹配也是先搜索,但是要排除網易源,然後根據搜索結果去匹配。搜索的時候,可以將 「歌曲名稱 + 歌手名稱」 組合用來搜索。
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;
}
軟體介面
軟體介面,增加用戶、密碼輸入
搜索結果,設置為默認選中:
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下載
//github.com/jadepeng/music163tool -
中國gitee地址:
//gitee.com/jadepeng/music163tool
作者:Jadepeng
出處:jqpeng的技術記事本–//www.cnblogs.com/xiaoqi
您的支援是對部落客最大的鼓勵,感謝您的認真閱讀。
本文版權歸作者所有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。