您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Simple Youtube Video Downloader
当前为
// ==UserScript== // @name Youtube Video Downloader // @namespace http://tampermonkey.net/ // @author fb // @version 1.0 // @description Simple Youtube Video Downloader // @match https://www.youtube.com/watch* // @grant GM_xmlhttpRequest // @connect p.oceansaver.in // @license GPL-3.0-or-later // @run-at document-end // ==/UserScript== (function() { 'use strict'; let animInterval = null; let originalText = ''; const observer = new MutationObserver((mutations, obs) => { const actionsInner = document.querySelector('#actions-inner'); if (!actionsInner) return; obs.disconnect(); injectUI(actionsInner); }); observer.observe(document.body, { childList: true, subtree: true }); function injectUI(container) { if (document.getElementById('download-button')) return; const wrapper = document.createElement('div'); wrapper.style.display = 'flex'; wrapper.style.alignItems = 'center'; wrapper.style.marginBottom = "2px"; const select = document.createElement('select'); select.id = 'format'; select.className = 'doc'; select.style.marginRight = '8px'; select.innerHTML = ` <optgroup label="Audio"> <option value="mp3">MP3</option> <option value="m4a">M4A</option> <option value="webm">WEBM</option> <option value="aac">AAC</option> <option value="flac">FLAC</option> <option value="opus">OPUS</option> <option value="ogg">OGG</option> <option value="wav">WAV</option> </optgroup> <optgroup label="Video"> <option value="360">MP4 (360p)</option> <option value="480">MP4 (480p)</option> <option value="720">MP4 (720p)</option> <option selected value="1080">MP4 (1080p)</option> <option value="1440">MP4 (1440p)</option> <option value="4k">WEBM (4K)</option> </optgroup> `; const btn = document.createElement('button'); btn.id = 'download-button'; btn.textContent = 'Download'; btn.style.cursor = 'pointer'; btn.className = 'style-scope ytd-button-renderer'; btn.addEventListener('click', startDownload); wrapper.appendChild(select); wrapper.appendChild(btn); container.insertAdjacentElement('afterbegin', wrapper); } function startDownload() { const btn = document.getElementById('download-button'); if (!btn) return; const fmt = document.getElementById('format').value; const videoUrl = encodeURIComponent(window.location.href); const initUrl = `https://p.oceansaver.in/ajax/download.php?format=${fmt}&url=${videoUrl}`; startButtonAnimation(btn); GM_xmlhttpRequest({ method: 'GET', url: initUrl, responseType: 'json', onload(res) { const data = res.response; if (!data || !data.success) { stopButtonAnimation(); alert('❌ Failed to initialize download'); return; } pollProgress(data.progress_url); }, onerror() { stopButtonAnimation(); alert('❌ Network error while starting download'); } }); } function pollProgress(progressUrl) { const intervalId = setInterval(() => { GM_xmlhttpRequest({ method: 'GET', url: progressUrl, responseType: 'json', onload(res) { const p = res.response; if (!p) { clearInterval(intervalId); stopButtonAnimation(); return; } if (p.success) { clearInterval(intervalId); triggerFileDownload(p.download_url); stopButtonAnimation(); } else { console.log(`Download progress: ${p.progress || 'unknown'}`); } }, onerror() { console.error('Error polling download progress'); clearInterval(intervalId); stopButtonAnimation(); } }); }, 1500); } function triggerFileDownload(url) { const a = document.createElement('a'); a.href = url; a.download = ''; document.body.appendChild(a); a.click(); document.body.removeChild(a); } function startButtonAnimation(btn) { originalText = btn.textContent; btn.disabled = true; let dots = 0; animInterval = setInterval(() => { dots = (dots + 1) % 4; btn.textContent = 'Downloading' + '.'.repeat(dots); }, 500); } function stopButtonAnimation() { const btn = document.getElementById('download-button'); if (animInterval) { clearInterval(animInterval); animInterval = null; } if (btn) { btn.disabled = false; btn.textContent = originalText || 'Download'; } } })();