YouTube Shorts URL 转换按钮

将 YouTube Shorts 网址转换为常规的 YouTube 视频网址。

当前为 2023-10-18 提交的版本,查看 最新版本

  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.2
  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.  
  35. const lang = navigator.language;
  36. const langData = [
  37. {
  38. name: "English",
  39. match: ["en"],
  40. lang: {
  41. buttonText: "Convert Shorts URL",
  42. buttonTitle: "Convert Shorts URL to regular video URL",
  43. },
  44. },
  45. {
  46. name: "Chinese (Traditional)",
  47. match: ["zh-TW"],
  48. lang: {
  49. buttonText: "Shorts網址轉換",
  50. buttonTitle: "將Shorts網址轉換成一般影片網址",
  51. },
  52. },
  53. {
  54. name: "Japanese",
  55. match: ["ja"],
  56. lang: {
  57. buttonText: "YouTube Shorts URL コンバーター",
  58. buttonTitle: "YouTube Shorts URLを通常のYouTubeビデオURLに変換します",
  59. },
  60. },
  61. {
  62. name: "Chinese (Simplified)",
  63. match: ["zh-CN"],
  64. lang: {
  65. buttonText: "YouTube Shorts URL 转换按钮",
  66. buttonTitle: "将 YouTube Shorts 网址转换为常规的 YouTube 视频网址",
  67. },
  68. },
  69. {
  70. name: "Korean",
  71. match: ["ko"],
  72. lang: {
  73. buttonText: "YouTube Shorts URL 변환",
  74. buttonTitle: "YouTube Shorts URL을 일반 YouTube 비디오 URL로 변환합니다",
  75. },
  76. },
  77. {
  78. name: "Russian",
  79. match: ["ru"],
  80. lang: {
  81. buttonText: "Конвертировать URL YouTube Shorts",
  82. buttonTitle: "Преобразование URL YouTube Shorts в обычный URL видео YouTube",
  83. },
  84. },
  85. {
  86. name: "German",
  87. match: ["de"],
  88. lang: {
  89. buttonText: "YouTube Shorts URL Konvertierung",
  90. buttonTitle: "Konvertiere YouTube Shorts URL in reguläre YouTube Video URL",
  91. },
  92. },
  93. {
  94. name: "Spanish",
  95. match: ["es"],
  96. lang: {
  97. buttonText: "Botón de conversión de URL de YouTube Shorts",
  98. buttonTitle: "Convierte la URL de YouTube Shorts en una URL de video de YouTube normal",
  99. },
  100. },
  101. {
  102. name: "French",
  103. match: ["fr"],
  104. lang: {
  105. buttonText: "Bouton de conversion d'URL YouTube Shorts",
  106. buttonTitle: "Convertir l'URL YouTube Shorts en URL vidéo YouTube classique",
  107. },
  108. },
  109. {
  110. name: "Italian",
  111. match: ["it"],
  112. lang: {
  113. buttonText: "Pulsante di conversione URL YouTube Shorts",
  114. buttonTitle: "Converti l'URL YouTube Shorts in URL video YouTube normale",
  115. },
  116. },
  117. ];
  118.  
  119. function getLanguageData() {
  120. for (const data of langData) {
  121. if (data.match.includes(lang)) {
  122. return data.lang;
  123. }
  124. }
  125. return langData[0].lang; // Default to English if no match is found
  126. }
  127.  
  128. const languageData = getLanguageData();
  129.  
  130. function createConvertButton() {
  131. if (!convertButton) {
  132. convertButton = document.createElement('button');
  133. convertButton.textContent = languageData.buttonText;
  134. convertButton.style.position = 'fixed';
  135. convertButton.style.top = '150px';
  136. convertButton.style.right = '10px';
  137. convertButton.style.zIndex = '9999';
  138. convertButton.style.backgroundColor = '#FF0000';
  139. convertButton.style.color = '#FFFFFF';
  140. convertButton.style.fontSize = '24px';
  141. convertButton.style.padding = '10px 20px';
  142. convertButton.style.border = 'none';
  143. convertButton.style.borderRadius = '5px';
  144. convertButton.title = languageData.buttonTitle;
  145. document.body.appendChild(convertButton);
  146.  
  147. convertButton.addEventListener('click', convertURL);
  148. }
  149. }
  150.  
  151. function convertURL() {
  152. const currentURL = window.location.href;
  153. if (currentURL.includes("youtube.com/shorts/")) {
  154. const match = currentURL.match(/https:\/\/www\.youtube\.com\/shorts\/([A-Za-z0-9_-]+)/);
  155. if (match) {
  156. const videoID = match[1];
  157. const videoURL = `https://www.youtube.com/watch?v=${videoID}`;
  158. window.location.href = videoURL;
  159. }
  160. }
  161. }
  162.  
  163. function removeConvertButton() {
  164. if (convertButton) {
  165. convertButton.remove();
  166. convertButton = null;
  167. }
  168. }
  169.  
  170. function checkAndCreateButton() {
  171. if (window.location.href.includes("youtube.com/shorts/")) {
  172. createConvertButton();
  173. } else {
  174. removeConvertButton();
  175. }
  176. }
  177.  
  178. checkAndCreateButton();
  179.  
  180. window.addEventListener('popstate', checkAndCreateButton);
  181.  
  182. const observer = new MutationObserver(function(mutationsList, observer) {
  183. for (const mutation of mutationsList) {
  184. if (mutation.type === 'childList') {
  185. checkAndCreateButton();
  186. }
  187. }
  188. });
  189.  
  190. observer.observe(document.documentElement, { childList: true, subtree: true });
  191. })();