info.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. const request = async (method, url, data = null, headers = {}) => {
  2. return new Promise(function (resolve, reject) {
  3. const xhr = new XMLHttpRequest();
  4. xhr.open(method, url);
  5. // 设置请求头
  6. Object.keys(headers).forEach(function (key) {
  7. xhr.setRequestHeader(key, headers[key]);
  8. });
  9. xhr.onload = function () {
  10. if (xhr.status >= 200 && xhr.status < 300) {
  11. resolve(xhr.responseText);
  12. } else {
  13. reject(new Error('Request failed with status: ' + xhr.status));
  14. }
  15. };
  16. xhr.onerror = function () {
  17. reject(new Error('Request failed'));
  18. };
  19. xhr.send(data);
  20. });
  21. }
  22. getVideoDetail = async (url) => {
  23. const headers = {
  24. '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',
  25. }
  26. return request('GET', url, null, headers)
  27. .then(res => {
  28. let regex = /var ytInitialPlayerResponse\s*=\s*({.*?});/;
  29. let match = res.match(regex);
  30. if (!match || !match.length) {
  31. throw new Error('JSON not found.');
  32. }
  33. const ytInitialPlayerResponse = JSON.parse(match[1]);
  34. console.log(ytInitialPlayerResponse);
  35. const originVideoDetails = ytInitialPlayerResponse["videoDetails"];
  36. const thumbnails = []
  37. for (const item of originVideoDetails["thumbnail"]["thumbnails"]) {
  38. thumbnails.push({
  39. "url": item["url"],
  40. "width": item["width"] + "",
  41. "height": item["height"] + ""
  42. })
  43. }
  44. const formats = []
  45. for (const item of ytInitialPlayerResponse["streamingData"]["formats"].concat(ytInitialPlayerResponse["streamingData"]["adaptiveFormats"])) {
  46. if (item && item["signatureCipher"] && item["mimeType"]) {
  47. let urlRegex = /url=([^&]+)/;
  48. let match = item["signatureCipher"].match(urlRegex);
  49. if (!match) {
  50. continue;
  51. }
  52. const encodedUrl = match[1];
  53. const decodedUrl = decodeURIComponent(encodedUrl);
  54. formats.push({
  55. "width": item["width"] + "",
  56. "height": item["height"] + "",
  57. "type": item["mimeType"],
  58. "quality": item["quality"],
  59. "itag": item["itag"],
  60. "fps": item["fps"] + "",
  61. "bitrate": item["bitrate"] + "",
  62. "url": decodedUrl,
  63. "ext": "mp4",
  64. "vcodec": item["mimeType"],
  65. "acodec": item["mimeType"],
  66. "vbr": "0",
  67. "abr": "0",
  68. "container": "mp4_dash"
  69. })
  70. }
  71. }
  72. regex = /var ytInitialData\s*=\s*({.*?});/;
  73. match = res.match(regex);
  74. if (!match || !match.length) {
  75. throw new Error('JSON not found.');
  76. }
  77. if (!match || !match.length) {
  78. throw new Error('JSON not found.');
  79. }
  80. const ytInitialData = JSON.parse(match[1]);
  81. console.log(ytInitialData);
  82. const recommendInfo = [];
  83. for (const item of ytInitialData["contents"]["twoColumnWatchNextResults"]["secondaryResults"]["secondaryResults"]["results"]) {
  84. if (item["compactVideoRenderer"]) {
  85. const recommendVideo = item["compactVideoRenderer"];
  86. recommendInfo.push({
  87. "type": "gridVideoRenderer",
  88. "videoId": recommendVideo["videoId"],
  89. "title": recommendVideo["title"]["simpleText"],
  90. "thumbnails": recommendVideo["thumbnail"]["thumbnails"],
  91. "channelName": recommendVideo["longBylineText"]["runs"][0]["text"],
  92. "publishedTimeText": recommendVideo["publishedTimeText"]["simpleText"],
  93. "viewCountText": recommendVideo["viewCountText"]["simpleText"],
  94. "shortViewCountText": recommendVideo["shortViewCountText"]["simpleText"],
  95. "lengthText": recommendVideo["lengthText"]["simpleText"]
  96. })
  97. }
  98. }
  99. const videoDetails = {
  100. "isLiveContent": originVideoDetails["isLiveContent"],
  101. "title": originVideoDetails["title"],
  102. "thumbnails": thumbnails,
  103. "description": originVideoDetails["shortDescription"],
  104. "lengthSeconds": originVideoDetails["lengthSeconds"],
  105. "viewCount": originVideoDetails["viewCount"],
  106. "keywords": originVideoDetails["keywords"],
  107. "author": originVideoDetails["author"],
  108. "channelID": originVideoDetails["channelId"],
  109. "recommendInfo": recommendInfo,
  110. "channelURL": `https://www.youtube.com/channel/${originVideoDetails["channelId"]}`,
  111. "videoId": originVideoDetails["videoId"]
  112. }
  113. return {
  114. "code": 200,
  115. "msg": "",
  116. "data": {
  117. "videoDetails": videoDetails,
  118. "streamingData": {
  119. "formats": formats
  120. }
  121. },
  122. "id": "MusicDetailViewModel_detail_url"
  123. }
  124. })
  125. }