您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds buttons to download the video and audio of a Youtube video using YT-DLP, needs the YT-DLP Wrapper to work (https://gist.github.com/lolxnn/cfdfe72d0c5f6445ce8d846aa4bf9bcb)
// ==UserScript== // @name Youtube Video Downloader (YT-DLP) // @namespace http://tampermonkey.net/ // @version 0.1 // @description Adds buttons to download the video and audio of a Youtube video using YT-DLP, needs the YT-DLP Wrapper to work (https://gist.github.com/lolxnn/cfdfe72d0c5f6445ce8d846aa4bf9bcb) // @author lolxnn // @match *://*.youtube.com/* // @grant none // @license MIT // ==/UserScript== // Check existing video elements on page load document.querySelectorAll("video").forEach(addButtons); // Set up a mutation observer to detect newly added video elements const observer = new MutationObserver((mutations) => { mutations.forEach((mutation) => { mutation.addedNodes.forEach((node) => { if (node.nodeType === 1 && node.tagName === "VIDEO") { addButtons(node); } }); }); }); // Start observing const config = { childList: true, subtree: true }; observer.observe(document.body, config); function getWrapperStyle() { return ` position: absolute; top: 0.7rem; left: 0.7rem; display: flex; z-index: 9999; flex-direction: row; gap: 0.5rem; transition: opacity 0.3s; `; } function addButtons(node) { const videoDownloadButton = getVideoDownloadButton(); const audioDownloadButton = getAudioDownloadButton(); const wrapper = document.createElement("div"); wrapper.style = getWrapperStyle(); wrapper.id = "ytdlp-wrapper"; wrapper.appendChild(audioDownloadButton); wrapper.appendChild(videoDownloadButton); node.parentElement.appendChild(wrapper); // Set up event listeners to show the button on hover node.parentElement.addEventListener("mouseenter", (e) => { const wrapperElement = e.target.querySelector("#ytdlp-wrapper"); wrapperElement.style.opacity = 1; }); node.parentElement.addEventListener("mouseleave", (e) => { const wrapperElement = e.target.querySelector("#ytdlp-wrapper"); wrapperElement.style.opacity = 0; }); } // Button style function getButtonStyle() { return ` background-color: rgba(0, 0, 0, 0.8); color: white; border: none; padding: 0.5rem; border-radius: 0.5rem; font-size: 1rem; cursor: pointer; backdrop-filter: blur(0.5rem); `; } // Function to get the video URL function getVideoUrl() { // On youtube we need the base address and only the video ID, otherwise in case of a playlist multiple videos will be downloaded const videoId = new URLSearchParams(window.location.search).get("v"); return `https://www.youtube.com/watch?v=${videoId}`; } // Function to handle the presence of a video function getVideoDownloadButton() { // You can add more code here to interact with the video element const downloadButton = document.createElement("button"); downloadButton.textContent = "Download Video 🎥"; downloadButton.id = "ytdlp-video-download" downloadButton.style = getButtonStyle(); downloadButton.addEventListener("click", (e) => { // Get the video URL const videoUrl = getVideoUrl(); // Open the YTDL-PL link openYTDLPLink(videoUrl, "video"); // Prevent the video from stopping e.preventDefault(); e.stopPropagation(); }); return downloadButton; } function getAudioDownloadButton() { const downloadButton = document.createElement("button"); downloadButton.textContent = "Download Audio 🎵"; downloadButton.id = "ytdlp-audio-download" downloadButton.style = getButtonStyle(); downloadButton.addEventListener("click", (e) => { // Get the video URL const videoUrl = getVideoUrl(); // Open the YTDL-PL link openYTDLPLink(videoUrl, "audio"); // Prevent the video from stopping e.preventDefault(); e.stopPropagation(); }); return downloadButton; } function openYTDLPLink(url, type) { switch (type) { case "video": window.open(`yt-dlp-wrapper://?url=${btoa(url)}&video=1`); break; case "audio": window.open(`yt-dlp-wrapper://?url=${btoa(url)}&audio=1`); break; default: break; } }