// ==UserScript== // @name Emby海报下载 // @namespace http://tampermonkey.net/ // @version 1.7 // @description 在Emby界面悬停时显示海报下载按钮 // @author You // @match http*://*/web/index.html* // @grant none // @require https://code.jquery.com/jquery-3.6.0.min.js // @license MIT // @downloadURL https://update.greasyfork.icu/scripts/533279/Emby%E6%B5%B7%E6%8A%A5%E4%B8%8B%E8%BD%BD.user.js // @updateURL https://update.greasyfork.icu/scripts/533279/Emby%E6%B5%B7%E6%8A%A5%E4%B8%8B%E8%BD%BD.meta.js // ==/UserScript== (function () { "use strict"; // 调试模式 const DEBUG = true; function debugLog(...args) { if (DEBUG) { console.log("[Emby海报下载]", ...args); } } // 检查jQuery是否可用 if (typeof jQuery === "undefined") { debugLog("jQuery未加载,尝试使用原生JavaScript"); return; } // 创建一个独立的样式 const styleEl = document.createElement("style"); styleEl.id = "emby-poster-downloader-style"; styleEl.textContent = ` .emby-poster-download-button { position: absolute; bottom: 100px; right: 5px; background-color: rgba(0, 0, 0, 0.7); color: white; border: none; border-radius: 4px; padding: 5px 10px; font-size: 12px; cursor: pointer; opacity: 0; transition: opacity 0.3s; z-index: 999; font-family: Arial, sans-serif; pointer-events: auto; } .emby-banner-download-button { position: absolute; bottom: 75px; right: 5px; background-color: rgba(0, 0, 0, 0.7); color: white; border: none; border-radius: 4px; padding: 5px 10px; font-size: 12px; cursor: pointer; opacity: 0; transition: opacity 0.3s; z-index: 999; font-family: Arial, sans-serif; pointer-events: auto; } /* 悬停时显示按钮 */ .cardOverlayContainer:hover .emby-poster-download-button, .cardBox:hover .emby-poster-download-button, .card:hover .emby-poster-download-button, .cardScalable:hover .emby-poster-download-button, .cardContent:hover .emby-poster-download-button, .cardImageContainer:hover .emby-poster-download-button, .itemsContainer .card:hover .emby-poster-download-button, .cardOverlayContainer:hover .emby-banner-download-button, .cardBox:hover .emby-banner-download-button, .card:hover .emby-banner-download-button, .cardScalable:hover .emby-banner-download-button, .cardContent:hover .emby-banner-download-button, .cardImageContainer:hover .emby-banner-download-button, .itemsContainer .card:hover .emby-banner-download-button { opacity: 1; } /* 详情页样式 */ .detailImageContainer .emby-poster-download-button { bottom: 40px; z-index: 10; } .detailImageContainer .emby-banner-download-button { bottom: 10px; z-index: 10; } .detailImageContainer:hover .emby-poster-download-button, .detailImageContainer:hover .emby-banner-download-button { opacity: 1; } `; document.head.appendChild(styleEl); // 跟踪添加按钮的itemId,避免重复 const processedIds = new Set(); // 标记正在处理,防止无限循环 let isProcessing = false; // 处理海报项目 function processPosterItems() { // 防止重复处理和无限循环 if (isProcessing) { return; } isProcessing = true; debugLog("开始处理海报项目"); // 首先移除所有现有的下载按钮 $(".emby-poster-download-button, .emby-banner-download-button").remove(); // 重置处理状态 processedIds.clear(); // 检查是否是详情页 const isDetailPage = window.location.hash.includes("/item?"); debugLog("是否为详情页:", isDetailPage); if (isDetailPage) { // 在详情页中,只处理detailImageContainer processDetailPage(); isProcessing = false; return; // 详情页只处理特定节点,不处理其他节点 } // 以下代码只在非详情页(列表页)执行 // 尝试多种选择器来匹配不同页面的海报容器 const selectors = [ // 用户提供的特定选择器 ".cardBox.cardBox-touchzoom.cardBox-bottompadded", ".cardOverlayContainer.itemAction.cardPadder-portrait.cardPadder-margin", ]; for (let selector of selectors) { const containers = $(selector); if (containers.length > 0) { debugLog(`使用选择器 ${selector} 找到 ${containers.length} 个容器`); processContainers(containers); } } // 如果上面的选择器都没找到,尝试直接找所有图片 if (processedIds.size === 0) { debugLog("尝试处理所有海报图片"); const allImages = $('img[src*="/Items/"]'); if (allImages.length > 0) { debugLog(`找到 ${allImages.length} 张图片`); allImages.each(function () { processImageElement($(this)); }); } } debugLog(`总共添加了 ${processedIds.size} 个下载按钮`); isProcessing = false; } // 处理图片元素 function processImageElement(img) { // 从图片URL提取itemId if (!img.attr("src") || !img.attr("src").includes("/Items/")) return; const match = img.attr("src").match(/\/Items\/([^\/]+)/); if (!match || !match[1]) return; const itemId = match[1]; // 如果此itemId已处理,跳过 if (processedIds.has(itemId)) return; // 寻找合适的父容器 const parentCard = img .closest(".card, .cardBox, .cardScalable, .cardOverlayContainer") .first(); if (!parentCard.length) return; // 确保父容器是相对定位 if (parentCard.css("position") !== "relative") { parentCard.css("position", "relative"); } // 创建下载按钮 createDownloadButton(parentCard, itemId); processedIds.add(itemId); } // 处理详情页 function processDetailPage() { // 在详情页中,只处理detailImageContainer const detailImageContainers = $(".detailImageContainer"); if (detailImageContainers.length > 0) { debugLog("找到详情页图片容器:", detailImageContainers.length); // 从URL获取itemId let itemId = ""; const match = window.location.hash.match(/item\?id=([^&]+)/); if (match && match[1]) { itemId = match[1]; } if (itemId) { detailImageContainers.each(function () { const container = $(this); // 确保容器是相对定位 if (container.css("position") !== "relative") { container.css("position", "relative"); } // 创建下载按钮 createDownloadButton(container, itemId); processedIds.add(itemId); }); } else { debugLog("详情页未找到itemId"); // 尝试从图片查找 detailImageContainers.each(function () { const container = $(this); const img = container.find('img[src*="/Items/"]'); if (img.length && img.attr("src")) { const imgMatch = img.attr("src").match(/\/Items\/([^\/]+)/); if (imgMatch && imgMatch[1]) { // 创建下载按钮 createDownloadButton(container, imgMatch[1]); processedIds.add(imgMatch[1]); } } }); } } } // 创建下载按钮 function createDownloadButton(container, itemId) { // 避免在同一容器添加多个按钮 if (container.find(".emby-poster-download-button").length) { return; } // 尝试获取标题 let itemName = ""; // 检查是否是详情页 const isDetailPage = window.location.hash.includes("/item?"); if (isDetailPage) { // 从详情页标题获取名称 const titleElement = $(".itemName-primary"); if (titleElement.length && titleElement.text()) { itemName = titleElement.text().trim(); debugLog(`创建按钮时从详情页获取到名称: ${itemName}`); } } else { // 在列表页寻找名称 // 直接在container中查找cardText元素 const nameElement = container.find( ".cardText.cardText-first.cardText-first-padded, .cardText-first" ); if (nameElement.length && nameElement.text()) { itemName = nameElement.text().trim(); debugLog(`创建按钮时从容器内部获取到名称: ${itemName}`); } // 如果没找到,查找container所在的卡片容器 if (!itemName) { const cardBox = container.closest(".cardBox, .card"); if (cardBox.length) { // 在卡片容器中查找名称元素 const cardTextElement = cardBox .find( ".cardText.cardText-first.cardText-first-padded, .cardText-first, [class*='cardText']" ) .first(); if (cardTextElement.length && cardTextElement.text()) { itemName = cardTextElement.text().trim(); debugLog(`创建按钮时从卡片容器获取到名称: ${itemName}`); } } } } // 创建海报下载按钮 const downloadBtn = $("