Img Downloader

Ajoute un bouton de téléchargement en haut à droite des images sur vos sites web favoris :p

  1. // ==UserScript==
  2. // @name Img Downloader
  3. // @namespace https://greasyfork.org/users/1429467
  4. // @version 1.0
  5. // @description Ajoute un bouton de téléchargement en haut à droite des images sur vos sites web favoris :p
  6. // @author Lakfu Sama
  7. // @match *://*.youtube.com/*
  8. // @match *://*.instagram.com/*
  9. // @match *://*.twitter.com/*
  10. // @match *://*.tiktok.com/*
  11. // @match *://*/*
  12. // @grant none
  13. // ==/UserScript==
  14.  
  15. (function() {
  16. 'use strict';
  17.  
  18. let autoShowButtons = true; // Par défaut, les boutons DL sont visibles
  19.  
  20. // Fonction pour créer un bouton de téléchargement
  21. function createDownloadButton(url) {
  22. let button = document.createElement("button");
  23. button.innerText = "DL";
  24. button.style.position = "absolute";
  25. button.style.top = "5px";
  26. button.style.right = "5px";
  27. button.style.backgroundColor = "rgba(0, 0, 0, 0.7)";
  28. button.style.color = "white";
  29. button.style.border = "none";
  30. button.style.padding = "5px 10px";
  31. button.style.borderRadius = "5px";
  32. button.style.cursor = "pointer";
  33. button.style.fontSize = "12px";
  34. button.style.zIndex = "1000";
  35. button.style.opacity = "0.8";
  36. button.style.transition = "opacity 0.2s";
  37. button.style.display = autoShowButtons ? "block" : "none";
  38.  
  39. // Effet de survol pour rendre le bouton plus visible
  40. button.onmouseover = () => button.style.opacity = "1";
  41. button.onmouseout = () => button.style.opacity = "0.8";
  42.  
  43. // Action du bouton pour télécharger la vidéo ou l'image
  44. button.onclick = () => {
  45. // Si l'URL est une ressource blob, cela peut être problématique (à contourner)
  46. if (url.startsWith("blob:")) {
  47. alert("Le téléchargement de vidéos blob n'est pas supporté directement. Utilisez un outil de téléchargement adapté.");
  48. } else {
  49. // Utilisation d'un proxy pour contourner le blocage direct des ressources
  50. let proxyUrl = "https://api.allorigins.win/raw?url="; // Utilisation d'un proxy CORS alternatif
  51. let finalUrl = proxyUrl + encodeURIComponent(url); // Encode l'URL pour éviter tout problème
  52. let a = document.createElement("a");
  53. a.href = finalUrl;
  54. a.download = "file"; // Nom générique pour le fichier
  55. document.body.appendChild(a);
  56. a.click();
  57. document.body.removeChild(a);
  58. }
  59. };
  60.  
  61. return button;
  62. }
  63.  
  64. // Fonction pour ajouter le bouton de téléchargement uniquement pour les vidéos et images valides
  65. function addDownloadButtons() {
  66. console.log("Recherche de vidéos et images...");
  67.  
  68. // Vérification des vidéos dans les balises <video>
  69. document.querySelectorAll("video").forEach(video => {
  70. if (!video.dataset.hasDownloadButton && video.src) {
  71. console.log("Vidéo trouvée: ", video.src);
  72. let button = createDownloadButton(video.src);
  73. video.style.position = "relative";
  74. video.parentNode.appendChild(button);
  75. video.dataset.hasDownloadButton = "true";
  76. }
  77. });
  78.  
  79. // Vérification des vidéos dans les tweets Twitter (balises <div> avec des liens de vidéo)
  80. document.querySelectorAll("div[data-testid='tweet']").forEach(tweet => {
  81. const video = tweet.querySelector("video"); // Cherche la vidéo dans le tweet
  82. if (video && !video.dataset.hasDownloadButton && video.src) {
  83. console.log("Vidéo Twitter trouvée: ", video.src);
  84. let button = createDownloadButton(video.src);
  85. video.style.position = "relative";
  86. video.parentNode.appendChild(button);
  87. video.dataset.hasDownloadButton = "true";
  88. }
  89. });
  90.  
  91. // Vérification des vidéos intégrées dans les <iframe> (ex. YouTube)
  92. document.querySelectorAll("iframe").forEach(iframe => {
  93. if (!iframe.dataset.hasDownloadButton && iframe.src && iframe.src !== "about:blank") {
  94. console.log("Iframe trouvée: ", iframe.src);
  95.  
  96. if (iframe.src.includes("youtube.com/embed/") || iframe.src.includes("vimeo.com")) {
  97. let videoUrl = iframe.src;
  98. let button = createDownloadButton(videoUrl);
  99. iframe.style.position = "relative";
  100. iframe.parentNode.appendChild(button);
  101. iframe.dataset.hasDownloadButton = "true";
  102. }
  103. }
  104. });
  105.  
  106. // Vérification des vidéos dans des <object> ou <embed> (cas plus anciens)
  107. document.querySelectorAll("object, embed").forEach(element => {
  108. if (!element.dataset.hasDownloadButton && element.data) {
  109. console.log("Vidéo object/embed trouvée: ", element.data);
  110. let button = createDownloadButton(element.data);
  111. element.style.position = "relative";
  112. element.parentNode.appendChild(button);
  113. element.dataset.hasDownloadButton = "true";
  114. }
  115. });
  116.  
  117. // Vérification des images (mais pas les petites)
  118. document.querySelectorAll("img").forEach(img => {
  119. if (!img.dataset.hasDownloadButton && img.src) {
  120. // Exclure les petites images (taille < 100x100)
  121. let imgWidth = img.naturalWidth;
  122. let imgHeight = img.naturalHeight;
  123. if (imgWidth > 100 && imgHeight > 100) {
  124. console.log("Image trouvée: ", img.src);
  125. let button = createDownloadButton(img.src);
  126. img.style.position = "relative";
  127. img.parentNode.appendChild(button);
  128. img.dataset.hasDownloadButton = "true";
  129. }
  130. }
  131. });
  132. }
  133.  
  134. // Observer pour les vidéos et images chargées dynamiquement (scroll infini)
  135. const observer = new MutationObserver(addDownloadButtons);
  136. observer.observe(document.body, { childList: true, subtree: true });
  137.  
  138. // Touche "D" pour afficher/cacher les boutons DL
  139. document.addEventListener('keydown', function(event) {
  140. if (event.key.toLowerCase() === 'd') {
  141. autoShowButtons = !autoShowButtons;
  142. document.querySelectorAll("button").forEach(button => {
  143. if (button.innerText === "DL") {
  144. button.style.display = autoShowButtons ? "block" : "none";
  145. }
  146. });
  147. }
  148. });
  149.  
  150. console.log("Script DL activé :\n[D] Afficher/Cacher les boutons de téléchargement");
  151.  
  152. // Appel immédiat pour initialiser le script
  153. addDownloadButtons();
  154. })();