YouTube Converter/Downloader

Adds a "Convert" button for easier downloading.

  1. // ==UserScript==
  2. // @name YouTube Converter/Downloader
  3. // @version 1.1.0
  4. // @description Adds a "Convert" button for easier downloading.
  5. // @author csuti
  6. // @match https://www.youtube.com/*
  7. // @grant none
  8. // @compatible firefox
  9. // @compatible chrome
  10. // @compatible edge
  11. // @compatible opera
  12. // @namespace https://greasyfork.org/users/1269486
  13. // ==/UserScript==
  14.  
  15. (function() {
  16. 'use strict';
  17.  
  18. // Function to change the video URL
  19. function changeVideoUrl() {
  20. window.location.href = window.location.href.replace("youtube", "youtubepi");
  21. }
  22.  
  23. // Function to create the button
  24. function createButton() {
  25. var subscribeButton = document.querySelector(".ytd-subscribe-button-renderer");
  26. if (!subscribeButton) return;
  27.  
  28. if (document.querySelector(".custom-youtube-button")) return;
  29.  
  30. var newButton = document.createElement("button");
  31. newButton.className = "custom-youtube-button";
  32. newButton.innerHTML = '⟳ <strong>Convert</strong>';
  33.  
  34. var darkMode = document.documentElement.getAttribute("dark") !== null;
  35.  
  36. var buttonStyle = {
  37. marginLeft: "8px",
  38. backgroundColor: darkMode ? "rgba(90, 90, 90, 0.36)" : "#F7F7F7",
  39. color: darkMode ? "#FFFFFF" : "#404040",
  40. border: "none",
  41. padding: "9.66px 16px",
  42. cursor: "pointer",
  43. fontSize: "14px",
  44. borderRadius: "100px",
  45. transition: "background-color 0.3s",
  46. fontFamily: "'Roboto', sans-serif"
  47. };
  48.  
  49. Object.assign(newButton.style, buttonStyle);
  50.  
  51. newButton.addEventListener("mouseenter", function() {
  52. newButton.style.backgroundColor = darkMode ? "rgba(140, 140, 140, 0.36)" : "rgba(180, 180, 180, 0.36)";
  53. });
  54.  
  55. newButton.addEventListener("mouseleave", function() {
  56. newButton.style.backgroundColor = darkMode ? "rgba(90, 90, 90, 0.36)" : "#F7F7F7";
  57. });
  58.  
  59. newButton.addEventListener("click", changeVideoUrl);
  60.  
  61. subscribeButton.parentNode.insertBefore(newButton, subscribeButton.nextSibling);
  62. }
  63.  
  64. // Function to initialize the button creation
  65. function initialize() {
  66. createButton();
  67. // Observe changes to the DOM
  68. var observer = new MutationObserver(function(mutations) {
  69. mutations.forEach(function(mutation) {
  70. if (mutation.addedNodes) {
  71. Array.from(mutation.addedNodes).forEach(function(node) {
  72. if (node.nodeType === 1 && node.classList.contains("ytd-subscribe-button-renderer")) {
  73. createButton();
  74. }
  75. });
  76. }
  77. });
  78. });
  79.  
  80. observer.observe(document.documentElement, { childList: true, subtree: true });
  81. }
  82.  
  83. // Wait for the document to fully load
  84. window.addEventListener('load', initialize);
  85.  
  86. // Handle dynamic page changes in YouTube's single-page application
  87. var pageCheckInterval = setInterval(function() {
  88. if (document.querySelector(".ytd-subscribe-button-renderer")) {
  89. clearInterval(pageCheckInterval);
  90. initialize();
  91. }
  92. }, 1000);
  93. })();