m3u81.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. {
  2. proxy_rule: `
  3. (function() {
  4. const rules = [{
  5. url: /\\.m3u8(\\?.*)?$/i,
  6. target: "m3u8-proxy",
  7. handler: function(response, headers, request) {
  8. const fixAdM3u8Ai = ${fixAdM3u8Ai.toString()}
  9. // 执行智能去广告
  10. const newBody = fixAdM3u8Ai(
  11. request.url,
  12. headers,
  13. response.body.toString()
  14. );
  15. return { body: newBody };
  16. }
  17. }];
  18. /* 动态注册规则 */
  19. if (typeof registerProxyRules === 'function') {
  20. registerProxyRules(rules);
  21. }
  22. return rules;
  23. })()
  24. `
  25. }
  26. {
  27. proxy_rule: `js:
  28. (function(){
  29. const b = (s1, s2) => {
  30. let i = 0;
  31. while (i < s1.length && s1[i] === s2[i]) i++;
  32. return i;
  33. };
  34. const reverseString = str => [...str].reverse().join('');
  35. // 增强版同步请求(带超时处理)
  36. const syncRequest = url => {
  37. try {
  38. if (typeof $http !== 'undefined') {
  39. const res = $http.get(url, {timeout:5000});
  40. return res.status === 200 ? res.body : '';
  41. }
  42. const xhr = new XMLHttpRequest();
  43. xhr.open('GET', url, false);
  44. xhr.timeout = 5000;
  45. xhr.send();
  46. return xhr.status === 200 ? xhr.responseText : '';
  47. } catch(e) {
  48. console.error('请求失败:', e);
  49. return '';
  50. }
  51. };
  52. // 增强版路径处理(支持多重../解析)
  53. const urljoin = (base, path) => {
  54. try {
  55. // 处理base路径
  56. const baseParts = base.split('/').filter(p => p);
  57. const isAbsolute = base.startsWith('http') || base.startsWith('//');
  58. // 处理相对路径
  59. path.split('/').forEach(p => {
  60. if (p === '..') {
  61. if (baseParts.length > (isAbsolute ? 3 : 1)) baseParts.pop();
  62. } else if (p !== '.' && p) {
  63. baseParts.push(p);
  64. }
  65. });
  66. // 重构URL
  67. if (isAbsolute) {
  68. const protocol = baseParts[0] || 'http:';
  69. const host = baseParts[1] || '';
  70. return protocol + '//' + baseParts.slice(2).join('/');
  71. }
  72. return baseParts.join('/');
  73. } catch(e) {
  74. console.warn('路径解析失败:', base, path);
  75. return base + '/' + path;
  76. }
  77. };
  78. return [{
  79. url: /\\.m3u8(\\?.*)?$/i,
  80. handler: function({ body }) {
  81. try {
  82. // 预处理内容
  83. let ss = body.split(/\\r?\\n/)
  84. .map(line => line.trim())
  85. .filter(line => line)
  86. .map(line => {
  87. if (line.startsWith('#') || line === '') return line;
  88. // 增强路径处理
  89. const processed = urljoin(this.request.url, line);
  90. console.log('路径转换:', line, '=>', processed);
  91. return processed;
  92. });
  93. // FFZY专用处理
  94. if (/ffzy|feifan/.test(this.request.url)) {
  95. let adIndex = ss.findIndex((_,i,a) =>
  96. a[i] === '#EXT-X-DISCONTINUITY' &&
  97. a[i+5] === '#EXT-X-DISCONTINUITY'
  98. );
  99. if (adIndex > -1) {
  100. console.log('检测到FFZY广告序列');
  101. ss.splice(adIndex, 5*2+1);
  102. }
  103. }
  104. // 智能阈值计算
  105. const validLines = ss.filter(l => !l.startsWith('#') && l.length > 10);
  106. if (validLines.length < 2) return body; // 安全保护
  107. const firstPart = validLines[0];
  108. const lastPart = validLines[validLines.length-1];
  109. const threshold = Math.min(
  110. b(firstPart, lastPart),
  111. firstPart.split('/').pop().length - 3 // 允许3字符差异
  112. );
  113. // 广告过滤
  114. const result = ss.filter((line, index) => {
  115. if (!line.startsWith('#')) {
  116. if (b(firstPart, line) < threshold) {
  117. console.log('移除广告片段:', line);
  118. // 同步移除对应的EXTINF标记
  119. if (ss[index-1]?.startsWith('#EXTINF')) {
  120. ss.splice(index-1, 1);
  121. return false;
  122. }
  123. return false;
  124. }
  125. }
  126. return true;
  127. });
  128. return result.join('\\n');
  129. } catch(e) {
  130. console.error('M3U8处理异常:', e.message);
  131. return body; // 异常时返回原始内容
  132. }
  133. }
  134. }];
  135. })()`
  136. }