您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
【UI修正】校准指令理解,使用负外边距(margin-top: -20px)将主面板强制上移20像素,实现用户预期的视觉效果。
// ==UserScript== // @name SnapAny 全能媒体下载器 (Zero V5.0 负边距修正版) // @namespace http://tampermonkey.net/ // @version 5.0 // @description 【UI修正】校准指令理解,使用负外边距(margin-top: -20px)将主面板强制上移20像素,实现用户预期的视觉效果。 // @author Zero (全域系统工程师AI) // @match https://snapany.com/zh* // @icon https://snapany.com/favicon.ico // @grant GM_download // @grant GM_addStyle // @license MIT // ==/UserScript== (function() { 'use strict'; // ================================================================================= // 零号AI核心:配置与常量 (与V4.9一致) // ================================================================================= const 选择器_结果容器 = 'div.flex.h-full.flex-col.justify-center.gap-4.p-6'; const 选择器_作品文案 = '.text-center.text-sm.font-medium'; const 选择器_媒体链接 = 'a[download]'; const 注入面板ID = 'zero-downloader-panel'; const 图片域名特征 = 'douyinpic.com'; const 模态框ID = 'zero-modal-player'; // ================================================================================= // 零号AI核心:注入自定义样式 (V5.0 修正) // ================================================================================= GM_addStyle(` /* [V5.0 修正] 使用负外边距强制上移 */ #${注入面板ID} { border: 2px dashed #007bff; border-radius: 8px; padding: 15px; margin-top: -20px; background-color: #f8f9fa; } #${注入面板ID} h3 { margin-top: 0; margin-bottom: 15px; text-align: center; color: #333; font-weight: bold; } .zero-控制区 { display: flex; justify-content: space-between; align-items: center; padding: 15px 0; border-top: 1px solid #dee2e6; margin-top: 15px; } .zero-下载按钮 { background-color: #28a745; color: white; padding: 10px 20px; border: none; border-radius: 5px; cursor: pointer; font-size: 16px; font-weight: bold; transition: background-color 0.3s; } .zero-下载按钮:disabled { background-color: #cccccc; cursor: not-allowed; } .zero-全选标签 { font-size: 16px; cursor: pointer; display: flex; align-items: center; } .zero-全选复选框 { margin-right: 8px; width: 18px; height: 18px; cursor: pointer; } .zero-预览区 { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px; } .zero-媒体项 { position: relative; border: 1px solid #ddd; border-radius: 4px; overflow: hidden; background-color: #000; cursor: pointer; } .zero-媒体项 img, .zero-媒体项 video { width: 100%; height: 100%; object-fit: cover; display: block; pointer-events: none; } .zero-媒体复选框 { position: absolute; top: 8px; right: 8px; width: 22px; height: 22px; cursor: pointer; z-index: 10; background-color: rgba(255, 255, 255, 0.7); border: 1px solid #999; border-radius: 3px; } #${模态框ID} { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.85); z-index: 9999; display: flex; justify-content: center; align-items: center; } #${模态框ID} .modal-content { position: relative; max-width: 90vw; max-height: 90vh; } #${模态框ID} video { width: 100%; height: 100%; outline: none; } #${模态框ID} .close-button { position: absolute; top: -30px; right: 0; font-size: 30px; color: #fff; cursor: pointer; line-height: 1; font-family: Arial, sans-serif; } `); // ================================================================================= // 零号AI核心:页内沙箱播放器 (与V4.9一致) // ================================================================================= function 打开页内播放器(媒体) { if (document.getElementById(模态框ID)) return; const modal = document.createElement('div'); modal.id = 模态框ID; const modalContent = document.createElement('div'); modalContent.className = 'modal-content'; const video = document.createElement('video'); video.src = 媒体.downloadUrl; video.controls = true; video.autoplay = true; const closeButton = document.createElement('span'); closeButton.className = 'close-button'; closeButton.innerHTML = '×'; closeButton.title = '关闭 (Esc)'; modalContent.appendChild(closeButton); modalContent.appendChild(video); modal.appendChild(modalContent); document.body.appendChild(modal); const closeModal = () => { document.removeEventListener('keydown', handleEsc); modal.remove(); }; const handleEsc = (e) => { if (e.key === 'Escape') { closeModal(); } }; closeButton.addEventListener('click', closeModal); modal.addEventListener('click', (e) => { if (e.target === modal) { closeModal(); } }); document.addEventListener('keydown', handleEsc); video.focus(); } // ================================================================================= // 零号AI核心:通用媒体面板构建器 (与V4.9一致) // ================================================================================= function 构建通用媒体面板(锚点元素, 媒体对象列表) { if (!媒体对象列表 || 媒体对象列表.length === 0) return; const 总面板 = document.createElement('div'); 总面板.id = 注入面板ID; 总面板.innerHTML = `<h3>零号AI · 全能媒体下载器</h3>`; const 预览区 = document.createElement('div'); 预览区.className = 'zero-预览区'; 总面板.appendChild(预览区); 媒体对象列表.forEach(媒体 => { const 媒体项 = document.createElement('div'); 媒体项.className = 'zero-媒体项'; 媒体项.title = '点击或双击可全屏预览'; 媒体项.addEventListener('click', () => 打开页内播放器(媒体)); if (媒体.type === 'video') { const 视频元素 = document.createElement('video'); 视频元素.src = 媒体.downloadUrl; 视频元素.poster = 媒体.previewUrl; 视频元素.preload = 'metadata'; 媒体项.appendChild(视频元素); } else { const 图片元素 = document.createElement('img'); 图片元素.src = 媒体.previewUrl; 媒体项.appendChild(图片元素); } const 复选框 = document.createElement('input'); 复选框.type = 'checkbox'; 复选框.className = 'zero-媒体复选框'; 复选框.checked = true; 复选框.dataset.downloadUrl = 媒体.downloadUrl; 复选框.dataset.filename = 媒体.filename; 复选框.addEventListener('click', (e) => e.stopPropagation()); 媒体项.appendChild(复选框); 预览区.appendChild(媒体项); }); const 控制区 = document.createElement('div'); 控制区.className = 'zero-控制区'; const 全选标签 = document.createElement('label'); 全选标签.className = 'zero-全选标签'; const 全选复选框 = document.createElement('input'); 全选复选框.type = 'checkbox'; 全选复选框.className = 'zero-全选复选框'; 全选复选框.checked = true; 全选标签.appendChild(全选复选框); 全选标签.append(` 全选/反选 (${媒体对象列表.length})`); const 下载按钮 = document.createElement('button'); 下载按钮.className = 'zero-下载按钮'; 控制区.appendChild(全选标签); 控制区.appendChild(下载按钮); 总面板.appendChild(控制区); 锚点元素.parentNode.insertBefore(总面板, 锚点元素); const 更新下载按钮状态 = () => { const 选中复选框列表 = 预览区.querySelectorAll('.zero-媒体复选框:checked'); const 选中数量 = 选中复选框列表.length; 下载按钮.textContent = `下载选中 (${选中数量})`; 下载按钮.disabled = 选中数量 === 0; 全选复选框.checked = 选中数量 > 0 && 选中数量 === 媒体对象列表.length; 全选复选框.indeterminate = 选中数量 > 0 && 选中数量 < 媒体对象列表.length; }; 全选复选框.addEventListener('change', () => { 预览区.querySelectorAll('.zero-媒体复选框').forEach(cb => { cb.checked = 全选复选框.checked; }); 更新下载按钮状态(); }); 预览区.querySelectorAll('.zero-媒体复选框').forEach(cb => cb.addEventListener('change', 更新下载按钮状态)); 下载按钮.addEventListener('click', () => { const 选中列表 = 预览区.querySelectorAll('.zero-媒体复选框:checked'); 选中列表.forEach((cb, i) => { setTimeout(() => { GM_download({ url: cb.dataset.downloadUrl, name: cb.dataset.filename }); }, i * 200); }); 下载按钮.textContent = '下载任务已启动...'; 下载按钮.disabled = true; setTimeout(更新下载按钮状态, 3000); }); 更新下载按钮状态(); } // ================================================================================= // 零号AI核心:内容解析与分发器 (与V4.9一致) // ================================================================================= function 处理解析结果(结果容器) { if (document.getElementById(注入面板ID)) return; const 媒体链接元素列表 = Array.from(结果容器.querySelectorAll(选择器_媒体链接)); if (媒体链接元素列表.length === 0) return; const 文案元素 = 结果容器.querySelector(选择器_作品文案); const 基础文件名 = 文案元素 ? 文案元素.textContent.trim().replace(/[\\?%*:|"<>]/g, '_') : 'SnapAny下载'; let 媒体对象列表 = []; const 主媒体链接元素 = 媒体链接元素列表.find(el => !el.href.includes(图片域名特征) || el.download.match(/\.(mp4|mov|webm|mp3|m4a)$/i)); if (主媒体链接元素) { const 封面图链接元素 = 媒体链接元素列表.find(el => el !== 主媒体链接元素 && (el.href.includes(图片域名特征) || el.download.match(/\.(jpg|jpeg|png|webp)$/i))); const 原始文件名 = 主媒体链接元素.download || 'media.file'; const 文件扩展名 = 原始文件名.includes('.') ? 原始文件名.substring(原始文件名.lastIndexOf('.')) : '.mp4'; 媒体对象列表.push({ type: 'video', previewUrl: 封面图链接元素 ? 封面图链接元素.href : '', downloadUrl: 主媒体链接元素.href, filename: `${基础文件名}${文件扩展名}` }); } else { const 图片URL集合 = new Set(媒体链接元素列表.map(el => el.href)); let 索引 = 0; 图片URL集合.forEach(url => { 媒体对象列表.push({ type: 'image', previewUrl: url, downloadUrl: url, filename: `${基础文件名}_${String(++索引).padStart(2, '0')}.jpg` }); }); } 结果容器.style.display = 'none'; 构建通用媒体面板(结果容器, 媒体对象列表); } // ================================================================================= // 零号AI核心:启动入口与DOM监视 (与V4.9一致) // ================================================================================= console.log('[零号AI] SnapAny全能媒体下载器 V5.0 (负边距修正版) 已启动...'); const 观察器 = new MutationObserver((mutationsList) => { for (const mutation of mutationsList) { if (mutation.type === 'childList') { const 结果容器 = document.querySelector(选择器_结果容器); if (结果容器 && !document.getElementById(注入面板ID) && window.getComputedStyle(结果容器).display !== 'none') { 处理解析结果(结果容器); } } } }); 观察器.observe(document.body, { childList: true, subtree: true }); })();