某鹅通 通用m3u8获取 (适用于一级 _0.ts 改 .m3u8)

获取某鹅通m3u8内容 重新拼装真实ts地址和解密真实密钥 发送给扩展 (一级 _0.ts 改 .m3u8)

安装此脚本?
作者推荐脚本

您可能也喜欢小鹅通 通用m3u8获取

安装此脚本
  1. // ==UserScript==
  2. // @name 某鹅通 通用m3u8获取 (适用于一级 _0.ts 改 .m3u8)
  3. // @version 0.3.2
  4. // @description 获取某鹅通m3u8内容 重新拼装真实ts地址和解密真实密钥 发送给扩展 (一级 _0.ts 改 .m3u8)
  5. // @author mz
  6. // @match https://*/*
  7. // @match http://*/*
  8. // @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
  9. // @grant none
  10. // @run-at document-start
  11. // @license GPL v3
  12. // @namespace https://94cat.com/
  13. // ==/UserScript==
  14. (function () {
  15. 'use strict';
  16.  
  17. const _JSONparse = JSON.parse;
  18. JSON.parse = function () {
  19. let data = _JSONparse.apply(this, arguments);
  20. findMedia(data);
  21. return data;
  22. }
  23. JSON.parse.toString = function () {
  24. return _JSONparse.toString();
  25. }
  26. async function findMedia(data, raw = undefined, depth = 0) {
  27. for (let key in data) {
  28. if (typeof data[key] == "object") {
  29. if (depth > 25) { continue; }
  30. if (!raw) { raw = data; }
  31. findMedia(data[key], raw, ++depth);
  32. continue;
  33. }
  34. if (typeof data[key] == "string" && key == "video_urls" && data[key].slice(-4) == "__ba") {
  35. let base64 = data[key].replace("__ba", "");
  36. base64 = base64.replaceAll("@", "1").replaceAll("#", "2").replaceAll("$", "3").replaceAll("%", "4");
  37. let json = _JSONparse(atob(base64));
  38. if (!json) { return }
  39. for (let obj of json) {
  40. console.log("xet: obj.url=" + obj.url);
  41. fetch(obj.url).then(response => response.text())
  42. .then(m3u8 => {
  43. const lines = m3u8.split('\n');
  44. let keyFlag = false;
  45. let coreLine = ""
  46. let contentLineCount = 0
  47. for (let i = 0; i < lines.length; i++) {
  48. if (!keyFlag && lines[i].includes("#EXT-X-KEY:METHOD=AES-128,URI=")) {
  49. const match = lines[i].match(/URI="([^"]*)"/);
  50. if (match && match[1]) {
  51. keyFlag = true;
  52. if (window.__user_id) {
  53. getKey(match[1] + "&uid=" + window.__user_id, window.__user_id);
  54. } else if (document.cookie) {
  55. for (let cookie of document.cookie.split(';')) {
  56. cookie = cookie.trim();
  57. if (cookie.substring(0, 10) == "userInfo={") {
  58. cookie = cookie.slice(9);
  59. cookie = isJSON(cookie);
  60. cookie && cookie.user_id && getKey(match[1] + "&uid=" + cookie.user_id, cookie.user_id);
  61. break;
  62. }
  63. }
  64. }
  65. }
  66. continue;
  67. }
  68. if (lines[i][0] != "#") {
  69. contentLineCount++
  70. if (lines[i].includes("start=0&") || (lines[i].includes("_0.ts") && contentLineCount == 1)) {
  71. coreLine = `${obj.ext.host}/${obj.ext.path}/${lines[i].replace("_0.ts", ".m3u8")}&${obj.ext.param}`;
  72. break;
  73. }
  74. }
  75. }
  76. console.log("xet: coreLine=" + coreLine);
  77. // = coreLine;
  78. //let url = URL.createObjectURL(new Blob([new TextEncoder("utf-8").encode(m3u8)]));
  79. window.postMessage({ action: "catCatchAddMedia", url: coreLine, href: location.href, ext: "m3u8" });
  80. });
  81. }
  82. }
  83. }
  84. }
  85. function uid2byte(uid) {
  86. const byteArray = new Array;
  87. for (let i = 0; i < uid.length; i++) {
  88. let temp = uid.charCodeAt(i);
  89. if (temp >= 65536 && temp <= 1114111) {
  90. byteArray.push(temp >> 18 & 7 | 240);
  91. byteArray.push(temp >> 12 & 63 | 128);
  92. byteArray.push(temp >> 6 & 63 | 128);
  93. byteArray.push(63 & temp | 128);
  94. } else if (temp >= 2048 && temp <= 65535) {
  95. byteArray.push(temp >> 12 & 15 | 224);
  96. byteArray.push(temp >> 6 & 63 | 128);
  97. byteArray.push(63 & temp | 128);
  98. } else if (temp >= 128 && temp <= 2047) {
  99. byteArray.push(temp >> 6 & 31 | 192);
  100. byteArray.push(63 & temp | 128);
  101. } else {
  102. byteArray.push(255 & temp);
  103. }
  104. }
  105. return byteArray;
  106. }
  107. function getKey(url, userId) {
  108. fetch(url).then(response => response.arrayBuffer())
  109. .then(buffer => {
  110. let newKey = [];
  111. buffer = new Uint8Array(buffer);
  112. const uidByte = uid2byte(userId);
  113. for (let i in buffer) {
  114. newKey.push(buffer[i] ^ uidByte[i]);
  115. }
  116. console.log(newKey);
  117. window.postMessage({ action: "catCatchAddKey", key: newKey, href: location.href });
  118. });
  119. }
  120.  
  121. const _xhrOpen = XMLHttpRequest.prototype.open;
  122. XMLHttpRequest.prototype.open = function () {
  123. this.addEventListener("readystatechange", function (event) {
  124. const isJson = isJSON(this.response);
  125. isJson && findMedia(isJson);
  126. });
  127. _xhrOpen.apply(this, arguments);
  128. }
  129. XMLHttpRequest.prototype.open.toString = function () {
  130. return _xhrOpen.toString();
  131. }
  132. function isJSON(str) {
  133. if (typeof str == "object") {
  134. return str;
  135. }
  136. if (typeof str == "string") {
  137. try {
  138. return _JSONparse(str);
  139. } catch (e) { return false; }
  140. }
  141. return false;
  142. }
  143. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址