YouTube Web Tweaks

This script optimizes YouTube's performance by modifying configs, shorts redirect and much more!

当前为 2023-03-12 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name YouTube Web Tweaks
  3. // @version 2.6.0
  4. // @description This script optimizes YouTube's performance by modifying configs, shorts redirect and much more!
  5. // @author Magma_Craft
  6. // @license MIT
  7. // @match *://www.youtube.com/*
  8. // @namespace https://greasyfork.org/en/users/933798
  9. // @icon https://www.youtube.com/favicon.ico
  10. // @unwrap
  11. // @run-at document-start
  12. // @grant none
  13. // ==/UserScript==
  14.  
  15. // Modifiying yt.config flags to optimize loading times and disables animations
  16. (function() {
  17. window['yt'] = window['yt'] || {};
  18. yt['config_'] = yt.config_ || {};
  19. yt.config_['EXPERIMENT_FLAGS'] = yt.config_.EXPERIMENT_FLAGS || {};
  20.  
  21. var iv = setInterval(function() {
  22. yt.config_.IS_TABLET = true;
  23. yt.config_.DISABLE_YT_IMG_DELAY_LOADING = true;
  24. yt.config_.EXPERIMENT_FLAGS.polymer_verifiy_app_state = false;
  25. yt.config_.EXPERIMENT_FLAGS.warm_load_nav_start_web = false;
  26. yt.config_.EXPERIMENT_FLAGS.kevlar_player_response_swf_config_wrapper_killswitch = false;
  27. yt.config_.EXPERIMENT_FLAGS.desktop_delay_player_resizing = false;
  28. yt.config_.EXPERIMENT_FLAGS.desktop_player_touch_gestures = false;
  29. yt.config_.EXPERIMENT_FLAGS.web_animated_like = false;
  30. yt.config_.EXPERIMENT_FLAGS.web_animated_like_lazy_load = false;
  31. yt.config_.EXPERIMENT_FLAGS.render_unicode_emojis_as_small_images = true;
  32. yt.config_.EXPERIMENT_FLAGS.kevlar_refresh_on_theme_change = false;
  33. yt.config_.EXPERIMENT_FLAGS.kevlar_watch_cinematics = false;
  34. yt.config_.EXPERIMENT_FLAGS.kevlar_watch_comments_panel_button = true;
  35. yt.config_.EXPERIMENT_FLAGS.kevlar_watch_hide_comments_while_panel_open = true;
  36. yt.config_.EXPERIMENT_FLAGS.kevlar_watch_comments_ep_disable_theater = false;
  37. }, 1);
  38.  
  39. var to = setTimeout(function() {
  40. clearInterval(iv);
  41. }, 1000)
  42. })();
  43.  
  44. // Redirect shorts to watch page (Anti-Shorts script is required for faster experience)
  45. var oldHref = document.location.href;
  46. if (window.location.href.indexOf('youtube.com/shorts') > -1) {
  47. window.location.replace(window.location.toString().replace('/shorts/', '/watch?v='));
  48. }
  49. window.onload = function() {
  50. var bodyList = document.querySelector("body")
  51. var observer = new MutationObserver(function(mutations) {
  52. mutations.forEach(function(mutation) {
  53. if (oldHref != document.location.href) {
  54. oldHref = document.location.href;
  55. console.log('location changed!');
  56. if (window.location.href.indexOf('youtube.com/shorts') > -1) {
  57. window.location.replace(window.location.toString().replace('/shorts/', '/watch?v='));
  58. }
  59. }
  60. });
  61. });
  62. var config = {
  63. childList: true,
  64. subtree: true
  65. };
  66. observer.observe(bodyList, config);
  67. };
  68.  
  69. // CSS adjustments and other tweaks to apply (including removal of ads)
  70. (function() {
  71. ApplyCSS();
  72.  
  73. function ApplyCSS() {
  74. var styles = document.createElement("style");
  75. styles.innerHTML=`
  76. /* Remove 'Learning, Fashion and Podcasts' tab from the sidebar menu */
  77. ytd-guide-entry-renderer > a[href*="/channel/UCrpQ4p1Ql_hG8rKXIKM1MOQ"] {
  78. display: none !important;
  79. }
  80. ytd-guide-entry-renderer > a[href*="/channel/UCtFRv9O2AHqOZjjynzrv-xg"] {
  81. display: none !important;
  82. }
  83. #endpoint.yt-simple-endpoint.ytd-guide-entry-renderer.style-scope[title="Podcasts"] {
  84. display: none !important;
  85. }
  86.  
  87. /* Remove 'YouTube Kids' and 'YouTube TV' tabs from the 'More from YouTube' sidebar menu */
  88. #endpoint.yt-simple-endpoint.ytd-guide-entry-renderer.style-scope[title="YouTube Kids"] {
  89. display: none !important;
  90. }
  91. #endpoint.yt-simple-endpoint.ytd-guide-entry-renderer.style-scope[title="YouTube TV"] {
  92. display: none !important;
  93. }
  94.  
  95. /* Remove 'YouTube Music' tab if users have YouTube Premium */
  96. #endpoint.yt-simple-endpoint.ytd-guide-entry-renderer.style-scope[title="YouTube Music"] {
  97. display: none !important;
  98. }
  99.  
  100. #endpoint.yt-simple-endpoint.ytd-mini-guide-entry-renderer.style-scope[title="YouTube Music"] {
  101. display: none !important;
  102. }
  103.  
  104. /* Remove ads and annoyances */
  105. #player-ads,
  106. .adDisplay,
  107. .ad-container,
  108. .ytd-display-ad-renderer,
  109. .video-ads,
  110. #masthead-ad {
  111. display: none !important;
  112. }
  113.  
  114. .ytd-mealbar-promo-renderer {
  115. display: none !important
  116. }`
  117. document.head.appendChild(styles);
  118. }
  119. })();
  120.  
  121. let video
  122.  
  123. const observer = new MutationObserver(mutations => {
  124. for(const mutation of mutations) {
  125. for(const addedNode of mutation.addedNodes) {
  126. if(addedNode.className && (addedNode.classList.contains("ytp-ad-skip-button-slot") || addedNode.classList.contains("ytp-ad-overlay-close-button"))) {
  127. console.log("ytp-ad")
  128. addedNode.click()
  129. } else if(addedNode.className && addedNode.classList.contains("ad-showing")) {
  130. console.log("ad-showing")
  131. if(!isNaN(video.duration)) {
  132. video.play()
  133. video.currentTime = video.duration
  134. }
  135. } else if(addedNode.tagName === "VIDEO" && addedNode.classList.contains("html5-main-video")) {
  136. console.log("video")
  137. video = addedNode
  138. video.addEventListener("durationupdate", () => {
  139. console.log("durationupdate")
  140. video.play()
  141. video.currentTime = video.duration
  142. })
  143. video.addEventListener("timeupdate", () => {
  144. const adSkipButton = document.querySelector(".ytp-ad-skip-button-slot button,.ytp-ad-overlay-close-button")
  145. if(adSkipButton) {
  146. adSkipButton.click()
  147. }
  148. if(document.querySelector(".ad-showing")) {
  149. if(!isNaN(video.duration)) {
  150. video.play()
  151. video.currentTime = video.duration
  152. }
  153. }
  154. })
  155. }
  156. }
  157. }
  158. })
  159.  
  160. observer.observe(document.documentElement, { subtree: true, childList: true, attributes: true })
  161. var interval = setInterval(function() {
  162. window.wrappedJSObject._lact = Date.now();
  163. }, 300000);