// ==UserScript== // @name [M3U8-DL]媒体链接抓取器 // @namespace https://github.com/lzwme/m3u8-dl // @homepage https://m3u8-player.lzw.me/download.html // @supportURL https://github.com/lzwme/m3u8-dl/issues // @icon https://gh-proxy.org/raw.githubusercontent.com/lzwme/m3u8-dl/refs/heads/main/packages/frontend/public/logo.png // @version 1.0.4 // @description 自动抓取网页中的多种媒体链接(m3u8、mp4、mkv、avi、mov、音频等),支持可配置的媒体类型,支持跳转到 m3u8-dl webui 下载 // @author lzw // @updateURL https://gh-proxy.org/raw.githubusercontent.com/lzwme/m3u8-dl/refs/heads/main/client/m3u8-capture.user.js // @downloadURL https://raw.githubusercontent.com/lzwme/m3u8-dl/refs/heads/main/client/m3u8-capture.user.js // @match *://*/* // @grant GM_addElement // @grant GM_setValue // @grant GM_getValue // @grant GM_getResourceText // @grant GM_xmlhttpRequest // @grant unsafeWindow // @resource SwalJS https://s4.zstatic.net/ajax/libs/sweetalert2/11.16.1/sweetalert2.min.js // @resource SwalCSS https://s4.zstatic.net/ajax/libs/sweetalert2/11.16.1/sweetalert2.css // @resource TailwindCSS https://s4.zstatic.net/ajax/libs/tailwindcss/2.2.19/tailwind.min.css // @run-at document-idle // ==/UserScript== (function(){"use strict";const X="m3u8_capture_webui_url",N="m3u8_capture_exclude_urls",K="m3u8_capture_panel_pos",J="m3u8_capture_panel_visible",Q="m3u8_capture_media_ext_list",Z="m3u8_capture_auto_start",ee="m3u8_capture_title_replace_rules",te="m3u8_capture_auto_close_webui",ne="m3u8_capture_capture_headers",_e=["m3u8","mp4","mkv","avi","mov","wmv","flv","webm","m4v","m3u","m4a","aac","flac","ape","mp3","wav","ogg","wma"],Me=["localhost:6600","/example.com/","lzw.me","doubleclick.net"];function H(){return GM_getValue(X,"http://localhost:6600").replace(/\/$/,"")}function oe(){return GM_getValue(N,"")}function Le(e){GM_setValue(N,e)}function B(){const e=GM_getValue(Q,[]);return e&&Array.isArray(e)&&e.length>0?e:[..._e]}function Te(e){if(Array.isArray(e)&&e.length>0){const t=e.map(r=>r.trim().toLowerCase()).filter(r=>r&&/^[a-z0-9]+$/i.test(r));return GM_setValue(Q,t),t}return null}function Re(){return GM_getValue(K,null)}function Ue(e){GM_setValue(K,e)}function $e(){return GM_getValue(J,!1)}function re(e){GM_setValue(J,e)}function ae(){return GM_getValue(Z,!1)}function Ae(e){GM_setValue(Z,e)}function se(){return GM_getValue(ee,"")}function ke(e){GM_setValue(ee,e)}function ie(){return GM_getValue(te,!1)}function Ie(e){GM_setValue(te,e)}function le(){return GM_getValue(ne,!1)}function Be(e){GM_setValue(ne,e)}const h=window.top&&window.top!==window.self;function V(e,t=document.head,r="css"){const o=e.length<50?GM_getResourceText(e):e;return Promise.resolve(GM_addElement(t,r==="css"?"style":"script",{type:r==="css"?"text/css":"text/javascript",textContent:o}))}function We(){const e=B();return new RegExp(`\\.(${e.join("|")})(\\?|$|#)`,"i")}function _(e){const t=e||window.location.href;if(t.startsWith(H()))return!0;const r=[...Me],o=oe();o.trim()&&r.push(...o.split(` `).map(n=>n.trim()).filter(n=>n));for(const n of r)try{if(t.includes(n)||n.startsWith("/")&&n.endsWith("/")&&new RegExp(n.slice(1,-1)).test(t))return!0}catch(a){console.warn("[M3U8 Capture] 排除规则格式错误:",n,a)}return!1}function ce(e){return new Promise((t,r)=>{navigator.clipboard?.writeText?navigator.clipboard.writeText(e).then(()=>t(!0)).catch(()=>{ue(e)?t(!0):r(new Error("复制失败"))}):ue(e)?t(!0):r(new Error("复制失败"))})}function ue(e){try{const t=document.createElement("textarea");t.value=e,t.style.position="fixed",t.style.opacity="0",t.style.left="-9999px",document.body.appendChild(t),t.select(),t.setSelectionRange(0,e.length);const r=document.execCommand("copy");return document.body.removeChild(t),r}catch(t){return console.error("[M3U8 Capture] fallbackCopy failed:",t),!1}}function Pe(e){try{const t=new URL(e);return`${t.protocol}//${t.host}${t.pathname}`}catch{return e}}function D(e){return"touches"in e&&e.touches.length>0?{x:e.touches[0].clientX,y:e.touches[0].clientY}:"changedTouches"in e&&e.changedTouches.length>0?{x:e.changedTouches[0].clientX,y:e.changedTouches[0].clientY}:{x:e.clientX,y:e.clientY}}function de(e){if(!e||typeof e!="string"||e==="NaN"||e==="undefined")return"";const t=se();if(!t.trim())return e;try{const r=t.split(/,|\n/).map(n=>n.trim()).filter(n=>n);let o=e;for(const n of r)if(n)try{if(n.startsWith("/")&&n.endsWith("/")&&n.length>2){const a=n.lastIndexOf("/"),l=n.slice(1,a),c=n.slice(a+1),i=new RegExp(l,c);o=o.replace(i,"")}else o=o.replaceAll(n,"")}catch(a){console.warn("[M3U8 Capture] 标题替换规则格式错误:",n,a)}return o=o.replace(/\s+/g," ").trim(),o}catch(r){return console.warn("[M3U8 Capture] 应用标题替换规则失败:",r),e}}function Ge(e){return e==null?!0:Array.isArray(e)?e.length===0:Object.keys(e).length===0}function fe(e,t=!1){if(!e||Ge(e))return"";const r=Object.entries(e).map(([o,n])=>`${o}: ${n}`).join(` `);return t?encodeURIComponent(r):r}async function Oe(){let e=document.body;const t=o=>{e=o},r=()=>e;unsafeWindow.SetSwalTarget=t,window.SetSwalTarget=t,unsafeWindow.GetSwalTarget=r,window.GetSwalTarget=r;try{const o=GM_getResourceText("SwalJS").replace(/document\.body/g,"GetSwalTarget()"),n=()=>V(o,document.head||document.documentElement,"script").then(()=>{const a=window.Swal||window.Sweetalert2||unsafeWindow.Swal||unsafeWindow.Sweetalert2;a&&(window.Swal=a,unsafeWindow.Swal=a)}).catch(a=>{console.error("[M3U8 Capture] Failed to add SweetAlert2 script:",a)});document.head||document.documentElement?await n():document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>n()):setTimeout(n,50)}catch(o){console.error("[M3U8 Capture] Failed to load SweetAlert2:",o)}}function He(e,t){V(GM_getResourceText("SwalCSS").replace(/(\d+)rem/g,"$1em").replace(/:root *{/,`#${t.id} {`).replace(/body/g,""),e,"css"),setTimeout(()=>{const r=window.Swal;typeof window.SetSwalTarget=="function"&&r&&(window.SetSwalTarget(t),window.Swal=r.mixin({target:t}))},500)}function Ve(e){V(GM_getResourceText("TailwindCSS").replace(/(\d+)rem/g,"$1em"),e,"css")}let M=null,v=null,d=null,s=null,b=null,A=$e(),W=!1;const P={x:0,y:0};let L=!1;const G={x:0,y:0};let q={x:0,y:0},T=!1,R=null;const E={x:0,y:0};function pe(){if(M)return v;M=document.createElement("div"),M.id="m3u8-capture-shadow-host",M.style.cssText="position: fixed; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; z-index: 9999;",document.body.appendChild(M),v=M.attachShadow({mode:"open"});const e=document.createElement("div");e.id="m3u8-capture-swal-container",v.appendChild(e);const t=document.createElement("style");return t.textContent=[":host { all: initial; font-family: system-ui, -apple-system, sans-serif; font-size: 14px }","* { box-sizing: border-box; }",".hidden { display: none !important; }",`#${e.id},`,`#${e.id} * { pointer-events: auto !important; }`].join(` `),v.appendChild(t),He(v,e),Ve(v),Oe(),v}function me(){if(s||h)return;const e=pe();if(!e)return;s=document.createElement("div"),s.id="m3u8-capture-toggle-btn",s.style.cssText="position: fixed; bottom: 30vh; right: 20px; width: 50px; height: 50px; pointer-events: auto; z-index: 99998; will-change: transform;",s.className=`fixed bottom-10 right-5 w-[50px] h-[50px] bg-blue-500 rounded-full flex items-center justify-center cursor-move shadow-lg text-2xl transition-all duration-200 hover:scale-110 hover:shadow-xl select-none touch-none ${A?"hidden":"flex"}`;const t=document.createElement("span");t.textContent="🎬",s.appendChild(t),b=document.createElement("span"),b.id="m3u8-capture-toggle-badge",b.style.cssText="position: absolute; top: -4px; right: -4px; min-width: 18px; height: 18px; background: #ef4444; color: white; border-radius: 9px; font-size: 11px; font-weight: bold; display: flex; align-items: center; justify-content: center; padding: 0 4px; box-shadow: 0 2px 4px rgba(0,0,0,0.2); line-height: 1;",b.textContent="0",b.classList.add("hidden"),s.appendChild(b);const r=o=>{if(!s)return;L=!0,T=!1;const n=D(o);q={x:n.x,y:n.y};const a=s.getBoundingClientRect();G.x=n.x-a.left,G.y=n.y-a.top,E.x=a.left,E.y=a.top;const l=window.getComputedStyle(s);l.transform&&l.transform!=="none"&&(s.style.transform="none",s.style.left=`${a.left}px`,s.style.top=`${a.top}px`,s.style.right="auto",s.style.bottom="auto"),s.style.cursor="move",s.style.transition="none",o.preventDefault(),o.stopPropagation()};s.addEventListener("mousedown",r),s.addEventListener("touchstart",r,{passive:!1}),s.addEventListener("click",()=>{T||ge()}),s.addEventListener("touchend",o=>{L&&!T&&(o.preventDefault(),o.stopPropagation(),ge())},{passive:!1}),e.appendChild(s),z()}function z(){if(!b||h||!x)return;const e=x.size;e>0?(b.textContent=e>99?"99+":e.toString(),b.classList.remove("hidden")):b.classList.add("hidden")}function ge(){h||!xe()||(A=!0,re(!0),d&&(d.style.display="flex"),s&&s.classList.add("hidden"))}function j(){h||(A=!1,re(!1),d&&(d.style.display="none"),s?s.classList.remove("hidden"):me(),z())}function he(){const e=window.Swal;e&&e.fire({title:"确认清空",text:"确定要清空所有媒体链接吗?",icon:"warning",showCancelButton:!0,confirmButtonText:"确定",cancelButtonText:"取消",confirmButtonColor:"#3b82f6"}).then(t=>{t.isConfirmed&&x&&(x.clear(),Y())})}function xe(){if(!document.body||h)return null;if(d)return d;const e=pe();if(!e)return null;const t=document.createElement("div");t.id="m3u8-capture-panel";const r=Re(),o=r&&window.innerWidth>768?{left:`${Math.max(0,Math.min(r.x,window.innerWidth-450))}px`,top:`${Math.max(0,Math.min(r.y,window.innerHeight-350))}px`,right:"auto"}:{right:"20px",top:"30vh"};t.className="fixed w-[420px] max-w-[90vw] max-h-[85vh] bg-white border-2 border-blue-500 rounded-xl shadow-2xl font-sans flex flex-col",t.style.cssText=` position: fixed; width: 420px; max-width: 90vw; max-height: 85vh; pointer-events: auto; z-index: 1059; ${o.left?`left: ${o.left};`:""} ${o.top?`top: ${o.top};`:""} ${`right: ${o.right};`} display: ${A?"flex":"none"}; `,t.innerHTML=`
🎬 媒体链接抓取器 0
`,e.appendChild(t),d=t;const n=t.querySelector("#m3u8-capture-header");if(!n)return d;const a=f=>{const m=f.target;if(m.tagName==="BUTTON"||m.closest("button"))return;W=!0;const w=D(f),y=t.getBoundingClientRect();P.x=w.x-y.left,P.y=w.y-y.top,t.style.cursor="move",f.preventDefault(),f.stopPropagation()};n.addEventListener("mousedown",a),n.addEventListener("touchstart",a,{passive:!1});const l=f=>{const m=D(f);if(W&&d){f.preventDefault();const w=m.x-P.x,y=m.y-P.y,k=window.innerWidth-t.offsetWidth,I=window.innerHeight-t.offsetHeight,U=Math.max(0,Math.min(w,k)),$=Math.max(0,Math.min(y,I));t.style.left=`${U}px`,t.style.top=`${$}px`,t.style.right="auto",Ue({x:U,y:$})}if(L&&s){f.preventDefault();const w=m.x-G.x,y=m.y-G.y,k=window.innerWidth-s.offsetWidth,I=window.innerHeight-s.offsetHeight,U=Math.max(0,Math.min(w,k)),$=Math.max(0,Math.min(y,I));E.x=U,E.y=$,R||(R=requestAnimationFrame(()=>{s&&L&&(s.style.transform=`translate(${E.x}px, ${E.y}px)`,s.style.left="0",s.style.top="0",s.style.right="auto",s.style.bottom="auto"),R=null})),Math.sqrt((m.x-q.x)**2+(m.y-q.y)**2)>5&&(T=!0)}},c=f=>{W&&(W=!1,d&&(d.style.cursor="default"),f.preventDefault()),L&&(L=!1,R&&(cancelAnimationFrame(R),R=null),s&&(s.style.cursor="move",s.style.transition="",T&&(s.style.transform=`translate(${E.x}px, ${E.y}px)`,s.style.left="0",s.style.top="0",s.style.right="auto",s.style.bottom="auto")),T&&f.preventDefault())};document.addEventListener("mousemove",l),document.addEventListener("mouseup",c),document.addEventListener("touchmove",l,{passive:!1}),document.addEventListener("touchend",c,{passive:!1}),document.addEventListener("touchcancel",c,{passive:!1});const i=f=>m=>{m.preventDefault(),m.stopPropagation(),f()},u=t.querySelector("#m3u8-capture-toggle");u&&(u.addEventListener("click",i(()=>j())),u.addEventListener("touchend",i(()=>j()),{passive:!1}));const p=t.querySelector("#m3u8-capture-clear");p&&(p.addEventListener("click",i(()=>he())),p.addEventListener("touchend",i(()=>he()),{passive:!1}));const g=t.querySelector("#m3u8-capture-settings");return g&&(g.addEventListener("click",i(()=>we())),g.addEventListener("touchend",i(()=>we()),{passive:!1})),!A&&!s&&me(),d}function we(e=v){const t=window.Swal;if(!t)return;const r=oe(),o=B(),n=ae(),a=se(),l=ie(),c=le();t.fire({title:"设置",html:`

支持的媒体文件扩展名,将用于识别和抓取媒体链接

匹配的网址将不展示面板且不抓取媒体链接

在获取标题后,将根据这些规则进行替换。支持正则表达式,格式:/pattern/flags 或 plain-text

启用后,跳转到下载页面时将自动触发开始下载(延迟1秒)

仅当"自动开始下载"开启时有效,开始下载后将自动关闭打开的WebUI页面

启用后,跳转下载时会携带请求 header。在需要登录、防盗链等场景下,可以提高成功率

`,showCancelButton:!0,confirmButtonText:"保存",cancelButtonText:"取消",confirmButtonColor:"#3b82f6",width:"600px",preConfirm:()=>{if(!e)return!1;const i=e.getElementById("swal-webui-url"),u=e.getElementById("swal-exclude-urls"),p=e.getElementById("swal-media-ext-list"),g=e.getElementById("swal-title-replace-rules"),f=e.getElementById("swal-auto-start"),m=e.getElementById("swal-auto-close-webui"),w=e.getElementById("swal-capture-headers"),y=i?i.value.trim():"",k=u?u.value.trim():"",I=p?p.value.trim():"",U=g?g.value.trim():"",$=f?f.checked:!1,Ee=m?m.checked:!1,Fe=w?w.checked:!1,Se=window.Swal;if(!y)return Se.showValidationMessage("WebUI 地址不能为空"),!1;const Ce=I.split(/[,\n\s]+/).map(F=>F.trim()).filter(F=>F);return Ce.length===0?(Se.showValidationMessage("媒体扩展名列表不能为空"),!1):{url:y,excludeUrls:k,mediaExtList:Ce,titleReplaceRules:U,autoStart:$,autoCloseWebui:Ee,captureHeaders:Fe}}}).then(i=>{if(i.isConfirmed&&i.value){const u=i.value;GM_setValue(X,u.url),Le(u.excludeUrls),Ae(u.autoStart),Ie(u.autoCloseWebui),ke(u.titleReplaceRules),Be(u.captureHeaders);const p=Te(u.mediaExtList),g=window.Swal;if(p&&g){let f=`已保存 ${p.length} 个媒体扩展名类型`;if(u.titleReplaceRules){const m=u.titleReplaceRules.split(",").filter(w=>w.trim()).length;f+=`
已设置 ${m} 个标题替换规则`}u.autoCloseWebui&&(f+="
已启用自动关闭WebUI页面"),g.fire({icon:"success",title:"设置已保存",html:f,timer:2500,showConfirmButton:!1})}else g&&g.fire({icon:"error",title:"保存失败",text:"媒体扩展名列表格式错误",timer:2e3,showConfirmButton:!1})}})}function be(e){const t=window.top&&window.top!==window;try{const o=window.open(e,"_blank");if(o&&!o.closed)return!0}catch(o){console.log("[M3U8 Capture] window.open failed:",o)}if(t&&window.top){try{const o=window.top.open(e,"_blank");if(o&&!o.closed)return!0}catch(o){console.log("[M3U8 Capture] window.top.open failed:",o)}try{return window.top.location.href=e,!0}catch(o){console.log("[M3U8 Capture] window.top.location.href failed:",o)}}const r=()=>{const o=window.Swal;o&&o.fire({icon:"info",title:"链接已复制",html:`由于 iframe 限制,链接已复制到剪贴板

${e}

请手动打开`,timer:4e3,showConfirmButton:!0,confirmButtonText:"确定"})};return ce(e).then(()=>r()).catch(()=>{const o=window.Swal;o&&o.fire({icon:"warning",title:"无法复制链接",html:`由于 iframe 限制,请手动复制并打开:

${e}`,confirmButtonText:"确定"})}),!1}function Y(){if(console.log("updateUI",h,x,d),h||!x||!xe()||!d)return;z();const e=d.querySelector("#m3u8-capture-list"),t=d.querySelector("#m3u8-capture-empty"),r=d.querySelector("#m3u8-capture-count");if(!e||!t||!r)return;if(r.textContent=x.size.toString(),x.size===0){e.classList.add("hidden"),t.classList.remove("hidden");return}e.classList.remove("hidden"),t.classList.add("hidden"),e.innerHTML="",Array.from(x.values()).sort((n,a)=>a.timestamp-n.timestamp).forEach(n=>{const a=document.createElement("div");a.className="border border-gray-200 rounded-lg p-3 bg-white transition-all duration-200 shadow-sm hover:bg-gray-50 hover:shadow-md";const l=n.title||"",c=n.type.toUpperCase();let i="bg-gray-500";c==="M3U8"||c==="M3U"?i="bg-blue-500":["MP4","MKV","AVI","MOV","WMV","FLV","WEBM","M4V","TS"].includes(c)?i="bg-green-500":["MP3","M4A","AAC","FLAC","APE","WAV","OGG","WMA"].includes(c)&&(i="bg-purple-500"),a.innerHTML=`
${l||"未命名媒体"} ${c}
${n.url}
`,e.appendChild(a)}),d.querySelectorAll(".m3u8-capture-download-btn").forEach(n=>{n.addEventListener("click",a=>{a.stopPropagation();const l=decodeURIComponent(n.getAttribute("data-url")||""),c=decodeURIComponent(n.getAttribute("data-title")||""),i=ae()?"&autoStart=1":"",u=i&&ie()?"&autoClose=1":"";let p=`${H()}/page/download?from=capture&action=new${i}${u}&url=${encodeURIComponent(l+(c?`|${c}`:""))}`;if(le()){let g=n.getAttribute("data-headers");g||(g=fe({referer:window.location.href,cookie:document.cookie},!0)),g&&(p+=`#headers=${g}`)}be(p)})}),d.querySelectorAll(".m3u8-capture-preview-btn").forEach(n=>{n.addEventListener("click",a=>{a.stopPropagation();const l=decodeURIComponent(n.getAttribute("data-url")||""),c=`https://m3u8-player.lzw.me?from=capture&url=${encodeURIComponent(l)}`;be(c)})}),d.querySelectorAll(".m3u8-capture-copy-btn").forEach(n=>{n.addEventListener("click",async a=>{a.stopPropagation();const l=n.getAttribute("data-url")||"",c=n.textContent,i=n.className;try{await ce(l),n.textContent="已复制",n.className="m3u8-capture-copy-btn bg-green-500 text-white border-none px-3.5 py-2 rounded-md cursor-pointer text-xs transition-all duration-200",setTimeout(()=>{n.textContent=c,n.className=i},2e3)}catch{const p=window.Swal;if(!p)return;p.fire({icon:"error",title:"复制失败",text:"请手动复制链接",html:`${l}`,confirmButtonText:"确定"})}})})}const x=new Map;function S(e,t="",r={}){if(e=qe(e)||e,!e||_(e))return;const o=Pe(e),n=x.get(o)||{},a=t||n.title||ye()||"",l={timestamp:Date.now(),url:e,pageUrl:window.location.href,title:de(a).trim(),type:De(e)||n.type||"",headers:Object.assign(r,n.headers||{})};if(h){try{console.log("send link to top window",l),window.top.postMessage({type:"m3u8-capture-link",data:l},"*")}catch(c){console.warn("[M3U8 Capture] Failed to send link to top window:",c)}return}x.set(o,l),Y()}function C(e){if(!e||typeof e!="string"||!e.startsWith("http"))return!1;const t=e.toLowerCase();return!!(We().test(t)||t.includes(".m3u8"))}function De(e){if(!e||typeof e!="string")return"media";const t=e.toLowerCase(),r=B();for(const o of r)if(new RegExp(`\\.${o}(\\?|$|#)`,"i").test(t))return o;return/m3u8/i.test(t)?"m3u8":"media"}function ye(e=document){let t="";const r=["h2.title","h1.title","div.sub-title","div.title","h2","h1"];for(const o of r){const n=e.querySelector(o);if(n&&(t=de(n.textContent),t))break}if(!t){try{h?t=ye(window.top.document):t=(e.title||"").split(/ [-|_] /)[0].trim()}catch{}console.log("title2",t,h)}return t}function qe(e){if(!e||typeof e!="string")return null;try{const t=new URL(e);for(const[r,o]of t.searchParams.entries()){if(!o)continue;const n=decodeURIComponent(o);if(C(n))return n}}catch{}return null}function ve(e){const t={};e instanceof Headers?e.forEach((o,n)=>{t[n.toLowerCase()]=o}):Object.keys(e).forEach(o=>{t[o.toLowerCase()]=e[o]});const r=["accept","accept-encoding","accept-language","connection","content-length","upgrade-insecure-requests"];return Object.keys(t).forEach(o=>{(r.includes(o)||o.startsWith("sec-")||t[o]==null)&&delete t[o]}),t}function ze(){const e=XMLHttpRequest.prototype.open,t=XMLHttpRequest.prototype.setRequestHeader,r=new WeakMap;XMLHttpRequest.prototype.open=function(n,a,l,c,i){return C(a.toString())&&(r.set(this,{}),this.addEventListener("load",function(){if(this.status>=200&&this.status<300){const u=r.get(this)||{},p=ve(u);S(a.toString(),"",p)}})),e.call(this,n,a,l??!0,c,i)},XMLHttpRequest.prototype.setRequestHeader=function(n,a){const l=r.get(this)||{};return l[n]=a,r.set(this,l),t.call(this,n,a)};const o=window.fetch;window.fetch=function(n,a){const l=typeof n=="string"?n:n&&typeof n=="object"&&"url"in n?n.url:"";if(C(l)){let c={};return a?.headers&&(a.headers instanceof Headers?a.headers.forEach((i,u)=>{c[u]=i}):Array.isArray(a.headers)?a.headers.forEach(([i,u])=>{c[i]=u}):c=a.headers),n instanceof Request&&n.headers.forEach((i,u)=>{c[u]=i}),o.call(this,n,a).then(i=>(i.ok&&S(l,"",ve(c)),i))}return o.call(this,n,a)}}function je(){if(typeof PerformanceObserver>"u")return;const e=new PerformanceObserver(t=>{for(const r of t.getEntries())r.name&&C(r.name)&&S(r.name)});try{e.observe({entryTypes:["resource"]})}catch{console.log("[M3U8 Capture] PerformanceObserver not supported")}}function O(){if(document.querySelectorAll("video").forEach(e=>{e.src&&C(e.src)&&S(e.src,e.getAttribute("title")||""),e.querySelectorAll("source").forEach(t=>{t.src&&C(t.src)&&S(t.src,e.getAttribute("title")||"")})}),document.querySelectorAll("a[href]").forEach(e=>{const t=e.getAttribute("href");if(t&&C(t))try{const r=new URL(t,window.location.href).href;S(r,e.textContent)}catch{}}),document.body){const e=document.body.innerText||"",r=B().join("|"),o=new RegExp(`https?:\\/\\/[^\\s"'<>]+\\.(${r})(\\?[^\\s"'<>]*)?`,"gi");let n;for(;(n=o.exec(e))!==null;)S(n[0])}}function Ye(){if(_())return;h||window.addEventListener("message",r=>{if(console.log("receive link from top window",r.data),r.data&&r.data.type==="m3u8-capture-link"&&r.data.data){const o=r.data.data;S(o.url,o.title,o.headers)}}),ze(),je();const e=()=>{if(console.log("initUI",h,_()),!_()){if(h)return O();document.body&&(O(),x.size>0&&Y())}};document.readyState==="loading"?document.addEventListener("DOMContentLoaded",e):setTimeout(e,100);let t=location.href;new MutationObserver(()=>{const r=location.href;if(r!==t){if(t=r,_()){j();return}setTimeout(()=>O(),1e3)}}).observe(document,{subtree:!0,childList:!0}),setInterval(()=>{document.body&&!_()&&O()},5e3)}Ye()})();