您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Gives you the opportunity to download the subtitles or go directly to the original YT video
// ==UserScript== // @name Edna.cz Subtitle Downloader // @name:cs Edna.cz Stahovač Titulků // @namespace https://greasyfork.org/users/30331-setcher // @author Setcher // @description Gives you the opportunity to download the subtitles or go directly to the original YT video // @description:cs Přidává možnost stáhnout titulky nebo přejít na původní YT video // @include http*://*edna.cz/* // @version 1.0.0 // @grant GM_addStyle // @grant GM_getValue // @grant GM_setValue // @grant GM_registerMenuCommand // ==/UserScript== (function() { 'use strict'; // Language settings const lang = { en: { downloadSubs: 'Download subtitles', noSubs: 'Subtitles not found', goToYT: 'Go to YouTube', noYT: 'YT link not found', menuOption: 'Open YT links in new tab', menuTitle: 'Settings', settingsTitle: 'Edna.cz Subtitle Downloader Settings', settingsAlt: 'Settings', closeButton: 'Close' }, cs: { downloadSubs: 'Stáhnout titulky', noSubs: 'Titulky nenalezeny', goToYT: 'Přejít na YouTube', noYT: 'YT link nenalezen', menuOption: 'Otevírat YT odkazy v novém panelu', menuTitle: 'Nastavení', settingsTitle: 'Nastavení pro Edna.cz Stahovač Titulků', settingsAlt: 'Nastavení', closeButton: 'Zavřít' } }; // Get current language const userLang = (navigator.language.startsWith('cs')) ? 'cs' : 'en'; const t = lang[userLang]; // Create settings dialog function showSettings() { const currentValue = GM_getValue('ytNewTab', false); let valueChanged = false; // Create dialog container with unique ID const dialog = document.createElement('div'); dialog.id = 'edna-settings-dialog'; dialog.style.cssText = ` position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); padding: 20px; border-radius: 5px; box-shadow: 0 0 10px rgba(0,0,0,0.5); z-index: 9999; font-family: Arial, sans-serif; min-width: 300px; background-color: #252338; `; // Add title const title = document.createElement('h3'); title.textContent = t.settingsTitle; title.style.marginTop = '0'; title.style.marginBottom = '20px'; dialog.appendChild(title); // Add checkbox const label = document.createElement('label'); label.style.display = 'flex'; label.style.alignItems = 'center'; label.style.margin = '15px 0'; label.style.cursor = 'pointer'; const checkbox = document.createElement('input'); checkbox.type = 'checkbox'; checkbox.checked = currentValue; checkbox.style.marginRight = '10px'; checkbox.addEventListener('change', function() { valueChanged = this.checked !== currentValue; }); label.appendChild(checkbox); label.appendChild(document.createTextNode(t.menuOption)); dialog.appendChild(label); // Add close button const closeButton = document.createElement('button'); closeButton.textContent = t.closeButton; closeButton.style.cssText = ` padding: 5px 15px; margin-top: 20px; float: right; background-color: #007bff; border: none; border-radius: 4px; color: white; cursor: pointer; `; closeButton.addEventListener('click', function() { GM_setValue('ytNewTab', checkbox.checked); document.body.removeChild(dialog); if (valueChanged) { location.reload(); } }); dialog.appendChild(closeButton); // Clear float const clearfix = document.createElement('div'); clearfix.style.clear = 'both'; dialog.appendChild(clearfix); // Add to page document.body.appendChild(dialog); } // Register settings menu GM_registerMenuCommand(t.menuTitle, showSettings); function addDownloadLinks() { const jwplayers = document.getElementsByClassName('video-box'); if (!jwplayers.length) return; for (let i = 0; i < jwplayers.length; i++) { let result, youtube; // Method 1: Check for data attributes const dataSource = jwplayers[i].querySelector('[data-video], [data-subtitles]'); if (dataSource) { const subtitles = dataSource.getAttribute('data-subtitles'); result = subtitles ? 'http://www.edna.cz/runtime/userfiles/' + subtitles.split("/").pop().replace(/\..+$/, '.srt') : null; youtube = dataSource.getAttribute('data-video'); } // Method 2: Fallback to regex else { const ytMatch = jwplayers[i].innerHTML.match(/video_id:\s"([^"]+)/); const srtMatch = jwplayers[i].innerHTML.match(/subtitles:\s*?"([^"]+)/); youtube = ytMatch ? ytMatch[1].replace(/\\/g, "") : null; result = srtMatch ? srtMatch[1].replace(/\\/g, "") : null; } // Create container for buttons const zNode = document.createElement('div'); zNode.style.cssText = 'text-align: center; margin: 20px 0; white-space: nowrap;'; // Subtitle download button const srtLink = document.createElement('a'); srtLink.textContent = result ? t.downloadSubs : t.noSubs; srtLink.className = result ? 'light-white btn btn-primary btn-sm' : 'btn btn-sm btn-warning'; if (result) { srtLink.href = result; srtLink.download = result.split("/").pop().split("?")[0]; } zNode.appendChild(srtLink); // Space between buttons zNode.appendChild(document.createTextNode(' ')); // YouTube link button const ytLink = document.createElement('a'); ytLink.textContent = youtube ? t.goToYT : t.noYT; ytLink.className = youtube ? 'light-white btn btn-primary btn-sm' : 'btn btn-sm btn-warning'; if (youtube) { ytLink.href = youtube; if (GM_getValue('ytNewTab', false)) { ytLink.target = '_blank'; ytLink.rel = 'noopener noreferrer'; } } zNode.appendChild(ytLink); // Space between buttons zNode.appendChild(document.createTextNode(' ')); // Settings button const settingsBtn = document.createElement('button'); settingsBtn.textContent = '⚙️'; settingsBtn.className = 'light-white btn btn-primary btn-sm' settingsBtn.name = t.settingsAlt; settingsBtn.addEventListener('click', showSettings); zNode.appendChild(settingsBtn); // Insert buttons jwplayers[i].parentNode.insertBefore(zNode, jwplayers[i].nextSibling); } } // Run when DOM is ready if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', addDownloadLinks); } else { addDownloadLinks(); } // CSS for buttons and modal - now properly scoped GM_addStyle(` .btn { display: inline-block !important; margin: 0 5px !important; white-space: nowrap !important; cursor: pointer !important; } /* Scoped to our dialog only */ #edna-settings-dialog { background-color: #343a40 !important; color: #f8f9fa !important; } #edna-settings-dialog h3 { color: inherit !important; } `); })();