NeteaseCloudMusicLyricProvider.cs 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. using BeatLyrics.Tool.DataProvider.OnlineLyric.Models;
  2. using BeatLyrics.Tool.Models;
  3. using Newtonsoft.Json;
  4. using System;
  5. using System.Linq;
  6. namespace BeatLyrics.Tool.DataProvider.OnlineLyric
  7. {
  8. public class NeteaseCloudMusicLyricProvider : LyricProvider
  9. {
  10. public override LyricSearchResultItem[] Search(string songName, string artist)
  11. {
  12. var url = $"https://music.163.com/api/search/get/web?hlposttag=&s={songName} {artist}&type=1&offset=0&total=true&limit=20";
  13. var wc = new System.Net.WebClient { Encoding = System.Text.Encoding.UTF8 };
  14. var json = wc.DownloadString(url);
  15. var parsed = JsonConvert.DeserializeAnonymousType(json, new
  16. {
  17. result = new
  18. {
  19. songs = new[]
  20. {
  21. new
  22. {
  23. id = 0,
  24. name = (string) null,
  25. duration=0,
  26. artists = new[]
  27. {
  28. new
  29. {
  30. name = (string) null,
  31. }
  32. },
  33. alias=(string[])null,
  34. }
  35. },
  36. }
  37. });
  38. var arr = parsed.result.songs.Select(p => new LyricSearchResultItem(nameof(NeteaseCloudMusicLyricProvider))
  39. {
  40. Id = p.id.ToString(),
  41. Name = p.name,
  42. Artists = string.Join(";", p.artists.Select(q => q.name)),
  43. Duration = p.duration,
  44. Remarks = string.Join(Environment.NewLine, p.alias)
  45. }).ToArray();
  46. return arr;
  47. }
  48. public override bool GetDetail(LyricSearchResultItem input)
  49. {
  50. if (input.ProviderName != nameof(NeteaseCloudMusicLyricProvider)) throw new ArgumentException("Provider no matched");
  51. var url = $"https://music.163.com/api/song/lyric?id={input.Id}&lv=1&kv=1&tv=1";
  52. var wc = new System.Net.WebClient { Encoding = System.Text.Encoding.UTF8 };
  53. var json = wc.DownloadString(url);
  54. var obj = JsonConvert.DeserializeAnonymousType(json, new
  55. {
  56. lrc = new
  57. {
  58. lyric = (string)null
  59. },
  60. klyric = new
  61. {
  62. lyric = (string)null
  63. },
  64. tlyric = new
  65. {
  66. lyric = (string)null
  67. }
  68. });
  69. if (string.IsNullOrWhiteSpace(obj.lrc?.lyric)) return false;
  70. input.DetailsText = obj.lrc.lyric;
  71. input.Details = ParseLrc(obj.lrc.lyric, input.Duration);
  72. if (input.Details.Count == 0)
  73. {
  74. var lines = obj.lrc.lyric.Split('\r', '\n');
  75. var pos = 0;
  76. var step = 1000;
  77. var len = 500;
  78. input.Details.Add(new LyricDetailExt
  79. {
  80. Text = "** Warning: Only text found **",
  81. DurationMs = len,
  82. TimeMs = pos,
  83. });
  84. pos += step;
  85. foreach (var line in lines)
  86. {
  87. if (string.IsNullOrWhiteSpace(line)) continue;
  88. input.Details.Add(new LyricDetailExt
  89. {
  90. Text = line,
  91. DurationMs = len,
  92. TimeMs = pos,
  93. });
  94. pos += step;
  95. }
  96. }
  97. if (false == string.IsNullOrWhiteSpace(obj.tlyric?.lyric))
  98. {
  99. input.DetailsTranslatedText = obj.tlyric.lyric;
  100. input.DetailsTranslated = ParseLrc(obj.tlyric.lyric, input.Duration);
  101. }
  102. input.IsDetailsLoaded = true;
  103. return true;
  104. }
  105. }
  106. }