20240510202815.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. (() => {
  2. var __webpack_exports__ = {};
  3. parseCodecs = e => {
  4. e = e.mimeType;
  5. if (!e) return {};
  6. e = e.match(/(?<mimetype>[^/]+\/[^;]+)(?:;\s*codecs="?(?<codecs>[^"]+))?/);
  7. if (!e) return {};
  8. e = e.groups.codecs;
  9. if (!e) return {};
  10. e = e.trim().replace(/,$/, "").split(",").map(e => e.trim()).filter(Boolean);
  11. let t = null, n = null;
  12. for (const i of e) {
  13. var o = i.split(".")[0];
  14. ["avc1", "avc2", "avc3", "avc4", "vp9", "vp8", "hev1", "hev2", "h263", "h264", "mp4v", "hvc1", "av01", "theora"].includes(o) ? t = t || i : ["mp4a", "opus", "vorbis", "mp3", "aac", "ac-3", "ec-3", "eac3", "dtsc", "dtse", "dtsh", "dtsl"].includes(o) ? n = n || i : console.warn("WARNING: Unknown codec " + i)
  15. }
  16. return t || n ? {vcodec: t, acodec: n} : 2 === e.length ? {vcodec: e[0], acodec: e[1]} : {}
  17. }, request = async (e, t, i = null, s = {}, n) => (n && (t = t.replace("https://www.youtube.com", "http://127.0.0.1")), console.log("请求url:" + t), console.log("请求data:" + i), console.log("请求method:" + e), console.log("请求headers:" + JSON.stringify(s)), n ? fetch(t, {
  18. method: e,
  19. headers: s,
  20. body: i
  21. }).then(e => e.text()) : new Promise((n, o) => {
  22. AF.request(t, e, i, s, (e, t) => {
  23. t ? (console.log("请求失败: " + t), o(t)) : n(e)
  24. })
  25. })), getStringBetween = (e, t, n, o = 0, i = 0) => {
  26. var s = e.indexOf(t), n = n ? e.indexOf(n, s) : e.length;
  27. return e.substring(s + t.length + i, n + o)
  28. }, getDecipherFunction = string => {
  29. const js = string.replace("var _yt_player={}", ""), top = getStringBetween(js, 'a=a.split("")', "};", 1, -28),
  30. beginningOfFunction = "var " + getStringBetween(top, 'a=a.split("")', "(", 10, 1).split(".")[0] + "=",
  31. side = getStringBetween(js, beginningOfFunction, "};", 2, -beginningOfFunction.length);
  32. return console.log("side: " + side), console.log("top: " + top), eval(side + top)
  33. };
  34. const cache = {};
  35. extractJSSignatureFunction = async (e, t) => {
  36. console.log("解析baseUrl: " + e);
  37. var n = "js:" + e;
  38. return cache[n] ? (console.log("从缓存中获取JSSignatureFunction: " + e), cache[n]) : (e = await request("GET", e, null, {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.101 Safari/537.36"}, t), (t = getDecipherFunction(e)) && (cache[n] = t), t)
  39. }, getUrlFromSignature = async (e, t, n) => {
  40. var t = await extractJSSignatureFunction(t, n), o = {};
  41. for (const l of e.split("&")) {
  42. var [i, s] = l.split("=");
  43. o[decodeURIComponent(i)] = decodeURIComponent(s)
  44. }
  45. var [n, r, a] = [o.url, o.s, o.sp];
  46. return console.log(e, n, r, a), n + `&${a}=` + t(r)
  47. }, detail = async (t, e) => {
  48. try {
  49. console.log("接受到解析请求: " + t);
  50. var n = await request("GET", t, null, {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.101 Safari/537.36"}, e),
  51. o = /var ytInitialPlayerResponse\s*=\s*({.*?});/, i = n.match(o);
  52. if (!i || !i.length) throw console.log("解释失败: 无法找到json"), new Error("JSON not found.");
  53. var s = JSON.parse(i[1]), r = s.videoDetails, a = (console.log("videoDetails: " + JSON.stringify(r)), []);
  54. for (const w of r.thumbnail.thumbnails) a.push({url: w.url, width: w.width + "", height: w.height + ""});
  55. var l, c, u, d = [],
  56. h = "https://www.youtube.com" + JSON.parse(n.match(/set\(({.+?})\);/)[1]).PLAYER_JS_URL;
  57. for (l of [].concat(s.streamingData.formats).concat(s.streamingData.adaptiveFormats)) console.log("current format: " + JSON.stringify(l)), l.url || (l.url = await getUrlFromSignature(l.signatureCipher, h, e)), l.url && ({
  58. vcodec: c,
  59. acodec: u
  60. } = parseCodecs(l), c) && u && d.push({
  61. width: l.width + "",
  62. height: l.height + "",
  63. type: l.mimeType,
  64. quality: l.quality,
  65. itag: l.itag,
  66. fps: l.fps + "",
  67. bitrate: l.bitrate + "",
  68. url: l.url,
  69. ext: "mp4",
  70. vcodec: c,
  71. acodec: u,
  72. vbr: "0",
  73. abr: "0",
  74. container: "mp4_dash"
  75. });
  76. if (o = /var ytInitialData\s*=\s*({.*?});/, !(i = n.match(o)) || !i.length) throw console.log("解析失败,无法找到 ytInitialData"), new Error("JSON not found.");
  77. var p, g = JSON.parse(i[1]), m = [];
  78. for (const x of g.contents.twoColumnWatchNextResults.secondaryResults.secondaryResults.results) x.compactVideoRenderer && (p = x.compactVideoRenderer, console.log("推荐视频: " + JSON.stringify(p)), p.videoId) && m.push({
  79. type: "gridVideoRenderer",
  80. videoId: p.videoId,
  81. title: p.title?.simpleText,
  82. thumbnails: p.thumbnail?.thumbnails,
  83. channelName: p.longBylineText?.runs?.[0]?.text,
  84. publishedTimeText: p.publishedTimeText?.simpleText,
  85. viewCountText: p.viewCountText?.simpleText,
  86. shortViewCountText: p.shortViewCountText?.simpleText,
  87. lengthText: p.lengthText?.simpleText
  88. });
  89. var v = {
  90. code: 200,
  91. msg: "",
  92. data: {
  93. videoDetails: {
  94. isLiveContent: r.isLiveContent,
  95. title: r.title,
  96. thumbnails: a,
  97. description: r.shortDescription,
  98. lengthSeconds: r.lengthSeconds,
  99. viewCount: r.viewCount,
  100. keywords: r.keywords,
  101. author: r.author,
  102. channelID: r.channelId,
  103. recommendInfo: m,
  104. channelURL: "https://www.youtube.com/channel/" + r.channelId,
  105. videoId: r.videoId
  106. }, streamingData: {formats: d}
  107. },
  108. id: "MusicDetailViewModel_detail_url"
  109. };
  110. return console.log("解析结果: " + JSON.stringify(v)), v
  111. } catch (e) {
  112. t = {code: -1, msg: e.toString()};
  113. return console.log("解析失败: " + JSON.stringify(t)), t
  114. }
  115. }, search = async (e, t, n) => {
  116. try {
  117. if (console.log("接受到搜索请求 keyword: " + e), console.log("接收到搜索请求 next: " + t), t) {
  118. var o = JSON.parse(t), i = o.key, s = {
  119. context: {client: {clientName: "WEB", clientVersion: "2.20240506.01.00"}},
  120. continuation: o.continuation
  121. },
  122. r = await request("POST", "https://www.youtube.com/youtubei/v1/search?key=" + i, JSON.stringify(s), {}, n),
  123. r = JSON.parse(r), a = [];
  124. for (const y of r.onResponseReceivedCommands[0].appendContinuationItemsAction.continuationItems[0].itemSectionRenderer.contents) {
  125. var l = y.videoRenderer;
  126. console.log("搜索结果: " + JSON.stringify(l)), l && l.videoId && a.push({
  127. type: "videoWithContextRenderer",
  128. data: {
  129. videoId: l.videoId,
  130. title: l.title?.runs?.[0]?.text,
  131. thumbnails: l.thumbnail?.thumbnails,
  132. channelName: l.longBylineText?.runs?.[0]?.text,
  133. publishedTimeText: l.publishedTimeText?.simpleText,
  134. viewCountText: l.viewCountText?.simpleText,
  135. shortViewCountText: l.shortViewCountText?.simpleText,
  136. lengthText: l.lengthText?.simpleText
  137. }
  138. })
  139. }
  140. var c = {
  141. code: 200,
  142. msg: "",
  143. data: {
  144. data: a,
  145. next: JSON.stringify({
  146. key: o.key,
  147. continuation: r.onResponseReceivedCommands[0].appendContinuationItemsAction.continuationItems[1].continuationItemRenderer.continuationEndpoint.continuationCommand.token
  148. })
  149. },
  150. id: "MusicSearchResultViewModel_search_result"
  151. };
  152. return console.log("携带next搜索结果成功: " + JSON.stringify(c)), c
  153. }
  154. var u = `https://www.youtube.com/results?q=${encodeURIComponent(e)}&sp=EgIQAQ%253D%253D`,
  155. d = await request("GET", u, null, {}, n), h = /var ytInitialData\s*=\s*({.*?});/, p = d.match(h);
  156. if (!p || !p.length) throw console.log("搜索失败:无法找到ytInitialData"), new Error("JSON not found.");
  157. var g, m = JSON.parse(p[1]), v = [];
  158. for (const T of m.contents.twoColumnSearchResultsRenderer.primaryContents.sectionListRenderer.contents[0].itemSectionRenderer.contents) T.videoRenderer && (g = T.videoRenderer, console.log("搜索结果: " + JSON.stringify(g)), g) && g.videoId && v.push({
  159. type: "videoWithContextRenderer",
  160. data: {
  161. videoId: g.videoId,
  162. title: g.title?.runs?.[0]?.text,
  163. thumbnails: g.thumbnail?.thumbnails,
  164. channelName: g.longBylineText?.runs?.[0]?.text,
  165. publishedTimeText: g.publishedTimeText?.simpleText,
  166. viewCountText: g.viewCountText?.simpleText,
  167. shortViewCountText: g.shortViewCountText?.simpleText,
  168. lengthText: g.lengthText?.simpleText
  169. }
  170. });
  171. var w = {},
  172. x = (0 < d.split("innertubeApiKey").length && (w.key = d.split("innertubeApiKey")[1].trim().split(",")[0].split('"')[2]), w.continuation = m.contents.twoColumnSearchResultsRenderer.primaryContents.sectionListRenderer.contents[1].continuationItemRenderer.continuationEndpoint.continuationCommand.token, {
  173. code: 200,
  174. msg: "",
  175. data: {data: v, next: JSON.stringify(w)},
  176. id: "MusicSearchResultViewModel_search_result"
  177. });
  178. return console.log("未携带next搜索结果成功: " + JSON.stringify(x)), x
  179. } catch (e) {
  180. t = {code: -1, msg: e.toString()};
  181. return console.log("搜索失败: " + JSON.stringify(t)), t
  182. }
  183. }
  184. })();