YouTube Shorts URL 轉換按鈕

將 YouTube Shorts 網址轉換為常規的 YouTube 影片網址。

目前為 2024-10-21 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name YouTube Shorts URL Conversion Button
  3. // @name:zh-TW YouTube Shorts URL 轉換按鈕
  4. // @name:ja YouTube Shorts URL コンバーター
  5. // @name:zh-CN YouTube Shorts URL 转换按钮
  6. // @name:ko YouTube Shorts URL 변환 버튼
  7. // @name:ru Кнопка преобразования URL YouTube Shorts
  8. // @name:de YouTube Shorts URL Konvertierungstaste
  9. // @name:es Botón de conversión de URL de YouTube Shorts
  10. // @name:fr Bouton de conversion d'URL YouTube Shorts
  11. // @name:it Pulsante di conversione URL YouTube Shorts
  12. // @namespace http://tampermonkey.net/
  13. // @version 1.6
  14. // @description Convert YouTube Shorts URL to regular YouTube video URL.
  15. // @description:zh-TW 將 YouTube Shorts 網址轉換為常規的 YouTube 影片網址。
  16. // @description:ja YouTube Shorts URLを通常のYouTubeビデオURLに変換します。
  17. // @description:zh-CN 将 YouTube Shorts 网址转换为常规的 YouTube 视频网址。
  18. // @description:ko YouTube Shorts URL을 일반 YouTube 비디오 URL로 변환합니다.
  19. // @description:ru Преобразование URL YouTube Shorts в обычный URL видео YouTube.
  20. // @description:de Konvertiere YouTube Shorts URL in reguläre YouTube Video URL.
  21. // @description:es Convierte la URL de YouTube Shorts en una URL de video de YouTube normal.
  22. // @description:fr Convertir l'URL YouTube Shorts en URL vidéo YouTube classique.
  23. // @description:it Converti l'URL YouTube Shorts in URL video YouTube normale.
  24. // @author 鮪魚大師
  25. // @match https://www.youtube.com/*
  26. // @grant none
  27. // @license MIT
  28. // ==/UserScript==
  29.  
  30. (function() {
  31. 'use strict';
  32.  
  33. let convertButton;
  34. let isButtonDown = false;
  35.  
  36. const lang = navigator.language;
  37. const langData = [
  38. {
  39. name: "English",
  40. match: ["en"],
  41. lang: {
  42. buttonText: "Convert",
  43. buttonTitle: "Convert Shorts URL to regular video URL",
  44. },
  45. },
  46. {
  47. name: "Chinese (Traditional)",
  48. match: ["zh-TW"],
  49. lang: {
  50. buttonText: "Shorts轉換",
  51. buttonTitle: "將Shorts網址轉換成一般影片網址",
  52. },
  53. },
  54. {
  55. name: "Japanese",
  56. match: ["ja"],
  57. lang: {
  58. buttonText: "Shorts変換",
  59. buttonTitle: "YouTube Shorts URLを通常のYouTubeビデオURLに変換します",
  60. },
  61. },
  62. {
  63. name: "Chinese (Simplified)",
  64. match: ["zh-CN"],
  65. lang: {
  66. buttonText: "Shorts转换",
  67. buttonTitle: "将 YouTube Shorts 网址转换为常规的 YouTube 视频网址",
  68. },
  69. },
  70. {
  71. name: "Korean",
  72. match: ["ko"],
  73. lang: {
  74. buttonText: "Shorts변환",
  75. buttonTitle: "YouTube Shorts URL을 일반 YouTube 비디오 URL로 변환합니다",
  76. },
  77. },
  78. {
  79. name: "Russian",
  80. match: ["ru"],
  81. lang: {
  82. buttonText: "Shorts конвертация",
  83. buttonTitle: "Преобразование URL YouTube Shorts в обычный URL видео YouTube",
  84. },
  85. },
  86. {
  87. name: "German",
  88. match: ["de"],
  89. lang: {
  90. buttonText: "Shorts konvertieren",
  91. buttonTitle: "Konvertiere YouTube Shorts URL in reguläre YouTube Video URL",
  92. },
  93. },
  94. {
  95. name: "Spanish",
  96. match: ["es"],
  97. lang: {
  98. buttonText: "Convertir Shorts",
  99. buttonTitle: "Convierte la URL de YouTube Shorts en una URL de video de YouTube normal",
  100. },
  101. },
  102. {
  103. name: "French",
  104. match: ["fr"],
  105. lang: {
  106. buttonText: "Convertir Shorts",
  107. buttonTitle: "Convertir l'URL YouTube Shorts en URL vidéo YouTube classique",
  108. },
  109. },
  110. {
  111. name: "Italian",
  112. match: ["it"],
  113. lang: {
  114. buttonText: "Converti Shorts",
  115. buttonTitle: "Converti l'URL YouTube Shorts in URL video YouTube normale",
  116. },
  117. },
  118. ];
  119.  
  120. function getLanguageData() {
  121. for (const data of langData) {
  122. if (data.match.includes(lang)) {
  123. return data.lang;
  124. }
  125. }
  126. return langData[0].lang;
  127. }
  128.  
  129. const languageData = getLanguageData();
  130.  
  131. function createConvertButton() {
  132. if (!convertButton) {
  133. convertButton = document.createElement('button');
  134. convertButton.textContent = languageData.buttonText;
  135. convertButton.style.position = 'fixed';
  136. convertButton.style.top = '150px';
  137. convertButton.style.right = '10px';
  138. convertButton.style.zIndex = '9999';
  139. convertButton.style.backgroundColor = '#FF0000';
  140. convertButton.style.color = '#FFFFFF';
  141. convertButton.style.fontSize = '24px';
  142. convertButton.style.padding = '10px 20px';
  143. convertButton.style.border = 'none';
  144. convertButton.style.borderRadius = '5px';
  145. convertButton.title = languageData.buttonTitle;
  146. document.body.appendChild(convertButton);
  147.  
  148. convertButton.addEventListener('click', convertURL);
  149.  
  150. convertButton.addEventListener('auxclick', function(event) {
  151. convertURL(event);
  152. });
  153.  
  154. convertButton.addEventListener('mousedown', function() {
  155. convertButton.style.backgroundColor = '#D80000';
  156. isButtonDown = true;
  157. });
  158.  
  159. convertButton.addEventListener('mouseup', function() {
  160. convertButton.style.backgroundColor = '#FF0000';
  161. isButtonDown = false;
  162. });
  163.  
  164. convertButton.addEventListener('mouseout', function() {
  165. if (!isButtonDown) {
  166. convertButton.style.backgroundColor = '#FF0000';
  167. }
  168. });
  169.  
  170. convertButton.addEventListener('mouseenter', function() {
  171. convertButton.style.backgroundColor = '#FF3333';
  172. });
  173.  
  174. convertButton.addEventListener('mouseleave', function() {
  175. convertButton.style.backgroundColor = '#FF0000';
  176. });
  177. }
  178. }
  179.  
  180. function convertURL(event) {
  181. const currentURL = window.location.href;
  182. if (currentURL.includes("youtube.com/shorts/")) {
  183. const match = currentURL.match(/https:\/\/www\.youtube\.com\/shorts\/([A-Za-z0-9_-]+)/);
  184. if (match) {
  185. const videoID = match[1];
  186. const videoURL = `https://www.youtube.com/watch?v=${videoID}`;
  187.  
  188. if (event && event.button === 2) {
  189. } else if (event && event.button === 1) {
  190. window.open(videoURL, '_blank');
  191. } else {
  192. window.location.href = videoURL;
  193. }
  194. }
  195. }
  196. }
  197.  
  198. function removeConvertButton() {
  199. if (convertButton) {
  200. convertButton.remove();
  201. convertButton = null;
  202. }
  203. }
  204.  
  205. function checkAndCreateButton() {
  206. if (window.location.href.includes("youtube.com/shorts/")) {
  207. createConvertButton();
  208. } else {
  209. removeConvertButton();
  210. }
  211. }
  212.  
  213. checkAndCreateButton();
  214.  
  215. window.addEventListener('popstate', checkAndCreateButton);
  216.  
  217. const observer = new MutationObserver(function(mutationsList, observer) {
  218. for (const mutation of mutationsList) {
  219. if (mutation.type === 'childList') {
  220. checkAndCreateButton();
  221. }
  222. }
  223. });
  224.  
  225. observer.observe(document.documentElement, { childList: true, subtree: true });
  226. })();