Youtube Thumbnail Button

Coloca um botão para ver thumbnail de um video do youtube

  1. // ==UserScript==
  2. // @name Youtube Thumbnail Button
  3. // @namespace https://greasyfork.org/users/715485
  4. // @version 1.1
  5. // @description Coloca um botão para ver thumbnail de um video do youtube
  6. // @author Luiz-lp
  7. // @icon https://www.freepnglogos.com/uploads/youtube-play-red-logo-png-transparent-background-6.png
  8. // @match *://*.youtube.com/*
  9. // @grant none
  10. // @license MIT
  11. // ==/UserScript==
  12.  
  13. (function() {
  14. 'use strict';
  15. const textStyle = `
  16. .thumbnail-button {
  17. display: table;
  18. margin-top:4px;
  19. cursor: pointer;
  20. color: rgb(255, 255, 255);
  21. border-top-left-radius: 3px;
  22. border-top-right-radius: 3px;
  23. border-bottom-right-radius: 3px;
  24. border-bottom-left-radius: 3px;
  25. background-color: #1b7adc;
  26.  
  27. }
  28. .thumbnail-text {
  29. display:block;
  30. cursor: pointer;
  31. color: rgb(255, 255, 255);
  32. background-color: #1b7adc;
  33. padding: 0.49em;
  34. }`;
  35. const BUTTON_ID = 'yt-thumbnail-luiz-lp-08012021';
  36. let currentUrl = document.location.href;
  37. let isPlaylist = currentUrl.includes("playlist");
  38.  
  39. css();
  40.  
  41. init(10);
  42.  
  43. locationChange();
  44.  
  45. function init(times) {
  46. for (let i = 0; i < times; i++) {
  47. setTimeout(delButton, 500 * i);
  48. setTimeout(findPanel, 500 * i);
  49. }
  50. }
  51.  
  52. function delButton() {
  53. if (!isPlaylist) return;
  54. document.querySelectorAll("#analytics-button.thumbnail-panel").forEach(panel => {
  55. panel.classList.remove("thumbnail-panel");
  56. panel.querySelector(".thumbnail-button").remove();
  57. });
  58. }
  59.  
  60. function findPanel() {
  61. if (isPlaylist) return;
  62. document.querySelectorAll("#analytics-button:not(.thumbnail-panel)").forEach(panel => {
  63. panel.classList.add("thumbnail-panel");
  64. addButton(panel);
  65. });
  66. }
  67.  
  68. function addButton(panel) {
  69.  
  70. const div = document.createElement('div');
  71. const select = document.createElement('select');
  72. const option = document.createElement('option');
  73.  
  74. div.classList.add("thumbnail-button");
  75.  
  76. div.id = BUTTON_ID;
  77.  
  78. select.id = 'thumbnail_selector';
  79.  
  80. select.classList.add("thumbnail-text");
  81.  
  82. option.textContent = "THUMBNAIL";
  83. option.selected = true;
  84. select.appendChild(option);
  85.  
  86. select.addEventListener('change', function () {
  87. download_thumbnail(this);
  88. }, false);
  89.  
  90. div.appendChild(select);
  91.  
  92. panel.insertBefore(div, panel.firstElementChild);
  93.  
  94. load_list(select);
  95.  
  96. }
  97.  
  98. async function download_thumbnail(selector) {
  99.  
  100. if (selector.selectedIndex == 0) {
  101. return;
  102. }
  103.  
  104. var m = currentUrl.match(/(?:watch\?.*v=|\/v\/)([\w\-=]+)/);
  105. var current_id = m[1];
  106. var url = "http://img.youtube.com/vi/"+ current_id +"/"+ selector.options[selector.selectedIndex].value +".jpg";
  107. window.open(url);
  108.  
  109. selector.options[0].selected = true;
  110. }
  111.  
  112. function load_list(select) {
  113.  
  114. var option = document.createElement('option');
  115. option.textContent = "HD (1280x720)";
  116. option.value = "maxresdefault";
  117. select.appendChild(option);
  118.  
  119. option = document.createElement('option');
  120. option.textContent = "SD (640x480)";
  121. option.value = "sddefault";
  122. select.appendChild(option);
  123.  
  124. option = document.createElement('option');
  125. option.textContent = "HQ (480x360)";
  126. option.value = "hqdefault";
  127. select.appendChild(option);
  128.  
  129. option = document.createElement('option');
  130. option.textContent = "MQ (320x180)";
  131. option.value = "mqdefault";
  132. select.appendChild(option);
  133. }
  134.  
  135. function css() {
  136. const style = document.createElement("style");
  137. style.type = "text/css";
  138. style.innerHTML = textStyle;
  139. document.head.appendChild(style);
  140. }
  141.  
  142. function locationChange() {
  143. const observer = new MutationObserver(mutations => {
  144. mutations.forEach(() => {
  145. if (currentUrl !== document.location.href) {
  146. currentUrl = document.location.href;
  147. isPlaylist = currentUrl.includes("playlist");
  148. init(10);
  149. }
  150. });
  151. });
  152. const target = document.body;
  153. const config = { childList: true, subtree: true };
  154. observer.observe(target, config);
  155. }
  156.  
  157. })();