您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
自动检测页面m3u8视频并进行完整下载
当前为
// ==UserScript== // @name m3u8视频侦测下载器【自动嗅探】 // @namespace https://tools.thatwind.com/ // @homepage https://tools.thatwind.com/tool/m3u8downloader // @version 1.0.1 // @description 自动检测页面m3u8视频并进行完整下载 // @author allFull // @match *://*/* // @icon https://tools.thatwind.com/favicon.png // @require https://cdn.jsdelivr.net/npm/[email protected]/dist/m3u8-parser.min.js // @grant unsafeWindow // @grant GM_openInTab // @grant GM_getValue // @grant GM_setValue // @grant GM_addStyle // @grant GM_xmlhttpRequest // @run-at document-start // @connect * // ==/UserScript== (function () { 'use strict'; if (location.host === "tools.thatwind.com") { GM_addStyle("#userscript-tip{display:none !important;}"); // 对请求做代理 const _fetch = unsafeWindow.fetch; unsafeWindow.fetch = async function (...args) { try { let response = await _fetch(...args); if (response.status !== 200) throw new Error(response.status); return response; } catch (e) { // 失败请求使用代理 if (args.length == 1) { console.log(`请求代理:${args[0]}`); return await new Promise((resolve, reject) => { let referer = new URLSearchParams(location.hash.slice(1)).get("referer"); let headers = {}; if (referer) { referer = new URL(referer); headers = { "origin": referer.origin, "referer": referer.href }; } GM_xmlhttpRequest({ method: "GET", url: args[0], responseType: 'arraybuffer', headers, onload(r) { resolve({ status: r.status, headers: new Headers(r.responseHeaders.split("\n").filter(n => n).map(s => s.split(/:\s*/)).reduce((all, [a, b]) => { all[a] = b; return all; }, {})), async text() { return r.responseText; }, async arrayBuffer() { return r.response; } }); }, onerror() { reject(new Error()); } }); }); } else { throw e; } } } return; } { // 请求检测 const _fetch = unsafeWindow.fetch; unsafeWindow.fetch = function (...args) { checkUrl(args[0]); return _fetch(...args); } const _open = unsafeWindow.XMLHttpRequest.prototype.open; unsafeWindow.XMLHttpRequest.prototype.open = function (...args) { checkUrl(args[1]); return _open.apply(this, args); } } const rootDiv = document.createElement("div"); rootDiv.style = ` position: fixed; z-index: 9999999999999999; opacity: 0.9; `; rootDiv.style.display = "none"; document.documentElement.appendChild(rootDiv); const shadowDOM = rootDiv.attachShadow({ mode: 'open' }); const wrapper = document.createElement("div"); shadowDOM.appendChild(wrapper); // 指示器 const bar = document.createElement("div"); bar.style = ` text-align: right; `; bar.innerHTML = ` <span class="number-indicator" data-number="0" style=" display: inline-flex; width: 25px; height: 25px; background: black; padding: 10px; border-radius: 100px; margin-bottom: 5px; cursor: pointer; " > <svg style=" filter: invert(1); " version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 585.913 585.913" style="enable-background:new 0 0 585.913 585.913;" xml:space="preserve"> <g> <path d="M11.173,46.2v492.311l346.22,47.402V535.33c0.776,0.058,1.542,0.109,2.329,0.109h177.39 c20.75,0,37.627-16.883,37.627-37.627V86.597c0-20.743-16.877-37.628-37.627-37.628h-177.39c-0.781,0-1.553,0.077-2.329,0.124V0 L11.173,46.2z M110.382,345.888l-1.37-38.273c-0.416-11.998-0.822-26.514-0.822-41.023l-0.415,0.01 c-2.867,12.767-6.678,26.956-10.187,38.567l-10.961,38.211l-15.567-0.582l-9.239-37.598c-2.801-11.269-5.709-24.905-7.725-37.361 l-0.25,0.005c-0.503,12.914-0.879,27.657-1.503,39.552L50.84,343.6l-17.385-0.672l5.252-94.208l25.415-0.996l8.499,32.064 c2.724,11.224,5.467,23.364,7.428,34.819h0.389c2.503-11.291,5.535-24.221,8.454-35.168l9.643-33.042l27.436-1.071l5.237,101.377 L110.382,345.888z M172.479,349.999c-12.569-0.504-23.013-4.272-28.539-8.142l4.504-17.249c3.939,2.226,13.1,6.445,22.373,6.687 c12.009,0.32,18.174-5.497,18.174-13.218c0-10.068-9.838-14.683-19.979-14.74l-9.253-0.052v-16.777l8.801-0.066 c7.708-0.208,17.646-3.262,17.646-11.905c0-6.121-4.914-10.562-14.635-10.331c-7.95,0.189-16.245,3.914-20.213,6.446l-4.52-16.693 c5.693-4.008,17.224-8.11,29.883-8.588c21.457-0.795,33.643,10.407,33.643,24.625c0,11.029-6.197,19.691-18.738,24.161v0.314 c12.229,2.216,22.266,11.663,22.266,25.281C213.89,338.188,197.866,351.001,172.479,349.999z M331.104,302.986 c0,36.126-19.55,52.541-51.193,51.286c-29.318-1.166-46.019-17.103-46.019-52.044v-61.104l25.711-1.006v64.201 c0,19.191,7.562,29.146,21.179,29.502c14.234,0.368,22.189-8.976,22.189-29.26v-66.125l28.122-1.097v65.647H331.104z M359.723,70.476h177.39c8.893,0,16.125,7.236,16.125,16.126v411.22c0,8.888-7.232,16.127-16.125,16.127h-177.39 c-0.792,0-1.563-0.116-2.329-0.232V380.782c17.685,14.961,40.504,24.032,65.434,24.032c56.037,0,101.607-45.576,101.607-101.599 c0-56.029-45.581-101.603-101.607-101.603c-24.93,0-47.749,9.069-65.434,24.035V70.728 C358.159,70.599,358.926,70.476,359.723,70.476z M390.873,364.519V245.241c0-1.07,0.615-2.071,1.586-2.521 c0.981-0.483,2.13-0.365,2.981,0.307l93.393,59.623c0.666,0.556,1.065,1.376,1.065,2.215c0,0.841-0.399,1.67-1.065,2.215 l-93.397,59.628c-0.509,0.4-1.114,0.61-1.743,0.61l-1.233-0.289C391.488,366.588,390.873,365.585,390.873,364.519z" /> </g> </svg> </span> `; wrapper.appendChild(bar); // 样式 const style = document.createElement("style"); style.innerHTML = ` .number-indicator{ position:relative; } .number-indicator::after{ content: attr(data-number); position: absolute; bottom: 0; right: 0; color: #40a9ff; font-size: 14px; font-weight: bold; background: #000; border-radius: 10px; padding: 3px 5px; } .download-btn:hover{ text-decoration: underline; } .download-btn:active{ opacity: 0.9; } .m3u8-item{ color: white; margin-bottom: 5px; display: flex; flex-direction: row; background: black; padding: 3px 10px; border-radius: 3px; font-size: 14px; user-select: none; } [data-shown="false"] { opacity: 0.8; zoom: 0.8; } [data-shown="false"]:hover{ opacity: 1; } [data-shown="false"] .m3u8-item{ display: none; } `; wrapper.appendChild(style); const barBtn = bar.querySelector(".number-indicator"); // 关于显隐和移动 let shown = GM_getValue("shown", true); wrapper.setAttribute("data-shown", shown); let x = GM_getValue("x", 10); let y = GM_getValue("y", 10); x = Math.min(innerWidth - 50, x); y = Math.min(innerHeight - 50, y); if (x < 0) x = 0; if (y < 0) y = 0; rootDiv.style.top = `${y}px`; rootDiv.style.right = `${x}px`; barBtn.addEventListener("mousedown", e => { let startX = e.pageX; let startY = e.pageY; let moved = false; let mousemove = e => { let offsetX = e.pageX - startX; let offsetY = e.pageY - startY; if (moved || (Math.abs(offsetX) + Math.abs(offsetY)) > 5) { moved = true; rootDiv.style.top = `${y + offsetY}px`; rootDiv.style.right = `${x - offsetX}px`; } }; let mouseup = e => { let offsetX = e.pageX - startX; let offsetY = e.pageY - startY; if (moved) { x -= offsetX; y += offsetY; GM_setValue("x", x); GM_setValue("y", y); } else { shown = !shown; GM_setValue("shown", shown); wrapper.setAttribute("data-shown", shown); } removeEventListener("mousemove", mousemove); removeEventListener("mouseup", mouseup); } addEventListener("mousemove", mousemove); addEventListener("mouseup", mouseup); }); function checkUrl(url) { url = new URL(url, location.href); if (url.pathname.endsWith(".m3u8") || url.pathname.endsWith(".m3u")) { // 发现 showM3U(url); } } let count = 0; async function showM3U(url) { // 解析 m3u const content = await (await fetch(url)).text(); const parser = new m3u8Parser.Parser(); parser.push(content); parser.end(); const manifest = parser.manifest; if (manifest.segments) { let duration = 0; manifest.segments.forEach((segment) => { duration += segment.duration; }); manifest.duration = duration; } let div = document.createElement("div"); div.className = "m3u8-item"; div.innerHTML = ` <span title="${url}" style=" max-width: 200px; text-overflow: ellipsis; white-space: nowrap; overflow: hidden; " >${url.pathname}</span> <span style=" margin-left: 10px; flex-grow: 1; " >${manifest.duration ? `${Math.ceil(manifest.duration * 10 / 60) / 10}分钟` : manifest.playlists ? `多线(${manifest.playlists.length})` : "未知时长"}</span> <span class="download-btn" style=" margin-left: 10px; cursor: pointer; ">下载</span> `; div.querySelector(".download-btn").addEventListener("click", () => { GM_openInTab( `https://tools.thatwind.com/tool/m3u8downloader#${new URLSearchParams({ m3u8: url.href, referer: location.href }) }`, { active: true } ); }); rootDiv.style.display = "block"; count++; bar.querySelector(".number-indicator").setAttribute("data-number", count); wrapper.appendChild(div); } })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址