// ==UserScript== // @name 爱给网音频助手-修复版本 // @namespace http://tampermonkey.net/ // @version 1.3 // @description 自动识别音频接口,支持所有页面的音频提取 // @author Kim // @match https://www.aigei.com/* // @grant GM_xmlhttpRequest // @run-at document-start // @license MIT // @downloadURL https://update.greasyfork.icu/scripts/573469/%E7%88%B1%E7%BB%99%E7%BD%91%E9%9F%B3%E9%A2%91%E5%8A%A9%E6%89%8B-%E4%BF%AE%E5%A4%8D%E7%89%88%E6%9C%AC.user.js // @updateURL https://update.greasyfork.icu/scripts/573469/%E7%88%B1%E7%BB%99%E7%BD%91%E9%9F%B3%E9%A2%91%E5%8A%A9%E6%89%8B-%E4%BF%AE%E5%A4%8D%E7%89%88%E6%9C%AC.meta.js // ==/UserScript== (function() { 'use strict'; let lastInterceptedUrl = ""; let activeBox = null; // --- 1. 底层拦截所有请求 --- const originOpen = XMLHttpRequest.prototype.open; XMLHttpRequest.prototype.open = function(method, url) { this.addEventListener('readystatechange', function() { if (this.readyState === 4 && this.status === 200) { try { const res = JSON.parse(this.responseText); // 只要返回的数据里有状态码和 message(Base64),就尝试解析 if (res.message && res.message.length > 20) { const decoded = atob(res.message); if (decoded.includes("http")) { lastInterceptedUrl = decoded; console.log("找到潜在音频链接:", lastInterceptedUrl); updateButtonStatus(lastInterceptedUrl); } } } catch (e) {} } }); originOpen.apply(this, arguments); }; // --- 2. 追踪用户最后点击的资源 --- document.addEventListener('mousedown', (e) => { const box = e.target.closest('.audio-item-box') || e.target.closest('.play-item'); if (box) { activeBox = box; console.log("当前锁定资源块:", box); } }, true); // --- 3. 更新按钮状态 --- function updateButtonStatus(url) { if (!activeBox) { // 如果没锁定,就更新页面上所有的“等待中”按钮 const allBtns = document.querySelectorAll(".gm-download-btn"); allBtns.forEach(b => setBtnReady(b, url)); return; } const btn = activeBox.querySelector(".gm-download-btn"); if (btn) setBtnReady(btn, url); } function setBtnReady(btn, url) { btn.innerHTML = "立即下载"; btn.style.background = "#ff4757"; btn.style.boxShadow = "0 0 10px rgba(255,71,87,0.5)"; btn.onclick = (e) => { e.preventDefault(); e.stopPropagation(); const title = btn.closest('.audio-item-box, .play-item')?.querySelector('.title-name, .name')?.innerText || "audio_" + Date.now(); doDownload(url, title); }; } // --- 4. 绕过403下载 --- function doDownload(url, name) { btnFeedback("下载中..."); GM_xmlhttpRequest({ method: "GET", url: url, headers: { "Referer": "https://www.aigei.com/" }, responseType: "blob", onload: function(res) { const blob = res.response; const link = document.createElement('a'); link.href = window.URL.createObjectURL(blob); link.download = name.replace(/[\\/:*?"<>|]/g, "_") + ".mp3"; link.click(); btnFeedback("下载成功"); }, onerror: () => alert("下载失败,请检查网络") }); } function btnFeedback(text) { if (activeBox) activeBox.querySelector(".gm-download-btn").innerHTML = text; } // --- 5. 注入下载按钮 --- function inject() { // 兼容搜索列表和详情页 const items = document.querySelectorAll(".audio-item-box, .play-item, .item-box"); items.forEach(item => { if (item.querySelector(".gm-download-btn")) return; const anchor = item.querySelector(".title-name") || item.querySelector(".name") || item.querySelector(".title"); if (!anchor) return; const btn = document.createElement("button"); btn.className = "gm-download-btn"; btn.innerHTML = "等待播放"; btn.style = "margin-left:10px; padding:3px 12px; border-radius:20px; border:none; background:#57606f; color:white; cursor:pointer; font-size:11px; transition: 0.3s;"; anchor.parentNode.insertBefore(btn, anchor.nextSibling); }); } setInterval(inject, 2000); })();