YouTube - Custom Default Settings

hide short, annotation, liveChat, etc.

  1. // ==UserScript==
  2. // @name YouTube - Custom Default Settings
  3. // @name:en YouTube - Custom Default Settings
  4. // @name:ja YouTube - 初期設定の変更
  5. // @namespace http://tampermonkey.net/
  6. // @version 2025-04-10
  7. // @description hide short, annotation, liveChat, etc.
  8. // @description:en hide short, annotation, liveChat, etc.
  9. // @description:ja 画質 次の動画への秒数 文字起こしの有無 ライブチャットの有無などの変更
  10. // @author ぐらんぴ
  11. // @match https://www.youtube.com/*
  12. // @icon https://www.youtube.com/favicon.ico
  13. // @run-at document-start
  14. // @grant GM_addStyle
  15. // @license MIT
  16. // ==/UserScript==
  17.  
  18. const settings = [
  19. // page: "watch"
  20. { name: 'liveChat', default: 'hide', /* show or hide */ },
  21. { name: 'transcript', default: 'hide', /* show or hide */ },
  22. { name: 'autoPlayCount', default: '0', /* 0 or more */ },
  23. { name: 'annotation', default: 'hide', /* show or hide */ },
  24. { name: 'quality', default: '720', /* 144, 240, 360, 480, 720, 1080 */ },
  25. { name: 'loop', default: 'on', /* on or off */ },
  26. { name: 'shuffle', default: 'on', /* on or off */ },
  27. // search
  28. { name: 'shorts', default: 'hide', /* show or hide */ },
  29. // promo, ad
  30. { name: 'promo', default: 'hide', /* show or hide */ }, // testing
  31. { name: 'ad', default: 'hide', /* show or hide */ }, // testing
  32. ];
  33. ///-----------------------------------------------------------------------------------///
  34. document.addEventListener('yt-page-data-fetched', e =>{
  35. let res = e.detail.pageData.response
  36. // console.log(e.detail.pageData.page);
  37. settings.forEach(s =>{
  38. try{
  39. if(e.detail.pageData.url == "/feed/you") return;
  40. // page: "watch"
  41. if(s.name == 'liveChat' && s.default == 'hide') res.contents.twoColumnWatchNextResults.conversationBar.liveChatRenderer.initialDisplayState = 'LIVE_CHAT_DISPLAY_STATE_COLLAPSED';
  42. if(s.name == 'transcript' && s.default == 'show'){
  43. let engagementPanels = res.engagementPanels
  44. engagementPanels.forEach(i =>{
  45. if(i.engagementPanelSectionListRenderer.targetId == 'engagement-panel-searchable-transcript') i.engagementPanelSectionListRenderer.visibility = 'ENGAGEMENT_PANEL_VISIBILITY_EXPANDED';
  46.  
  47. });
  48. }
  49. if(s.name == 'autoPlayCount'){
  50. res.playerOverlays.playerOverlayRenderer.autoplay.playerOverlayAutoplayRenderer.countDownSecs = s.default
  51. res.playerOverlays.playerOverlayRenderer.autoplay.playerOverlayAutoplayRenderer.countDownSecsForFullscreen = s.default
  52. }
  53. if(s.name == 'annotation' && s.default == 'hide'){ // https://i.ytimg.com/an/
  54. GM_addStyle(`
  55. .annotation {
  56. display: none;
  57. }`)
  58. }
  59. if(s.name == 'quality'){
  60. for (let i = 0; i < localStorage.length; i++) {
  61. let key = localStorage.key(i);
  62. if (key === "yt-player-quality") {
  63. let data = localStorage.getItem(key);
  64. // console.log(data);
  65.  
  66. let obj = JSON.parse(data);
  67. let innerData = JSON.parse(obj.data);
  68.  
  69. innerData.quality = s.default;
  70. obj.data = JSON.stringify(innerData);
  71.  
  72. let newData = JSON.stringify(obj);
  73. // console.log(newData);
  74.  
  75. localStorage.setItem(key, newData);
  76. }
  77. }
  78.  
  79. }
  80. // playList
  81. if(s.name == 'loop' && s.default == 'on' && e.detail.pageData.response.contents.twoColumnWatchNextResults.playlist){
  82. const loopId = setInterval(()=>{
  83. if(document.querySelector("[aria-label='Loop playlist']")){
  84. clearInterval(loopId);
  85. document.querySelector("[aria-label='Loop playlist']").click();
  86. }
  87. },1000);
  88. }
  89. if(s.name == 'shuffle' && s.default == 'on' && e.detail.pageData.response.contents.twoColumnWatchNextResults.playlist){
  90. const shuffleId = setInterval(()=>{
  91. if(document.querySelector("[aria-label='Shuffle playlist']").getAttribute("aria-pressed") == 'false'){
  92. clearInterval(shuffleId);
  93. document.querySelector("[aria-label='Shuffle playlist']").click();
  94. }
  95. },1000);
  96. }
  97. // search
  98. if(s.name == 'shorts' && s.default == 'hide'){
  99. // page: "browse" - top, "search"
  100. GM_addStyle(`
  101. ytd-reel-shelf-renderer {
  102. display: none;
  103. }
  104.  
  105. ytd-rich-shelf-renderer {
  106. display: none;
  107. }`)
  108. }
  109. // promo, ad
  110. if(s.name == 'promo' && s.default == 'hide') e.detail.pageData.playerResponse.messages[0].mealbarPromoRenderer = null;
  111. if(s.name == 'ad' && s.default == 'hide'){
  112. if(e.detail.pageData.page == "watch"){ // page: "watch"
  113. e.detail.pageData.playerResponse.auxiliaryUi = null; // testing
  114. }
  115. GM_addStyle(`
  116. ytd-ad-slot-renderer {
  117. display: none;
  118. }`)
  119. }
  120. }catch(err){ //console.log(err)
  121. }
  122. });
  123. });
  124.  
  125. const qualitySetting = settings.find(s => s.name === 'quality');
  126. if(qualitySetting){
  127. for(let i = 0; i < localStorage.length; i++){
  128. let key = localStorage.key(i);
  129. if(key === "yt-player-quality"){
  130. let data = localStorage.getItem(key);
  131.  
  132. if(data){
  133. try{
  134. // Parse the existing data
  135. let obj = JSON.parse(data);
  136. let innerData = JSON.parse(obj.data);
  137.  
  138. // Update quality with default value
  139. innerData.quality = qualitySetting.default;
  140. obj.data = JSON.stringify(innerData);
  141.  
  142. // Save back to localStorage
  143. let newData = JSON.stringify(obj);
  144. localStorage.setItem(key, newData);
  145.  
  146. // console.log('Quality updated to:', qualitySetting.default);
  147. }catch{}
  148. }
  149. }
  150. }
  151. }
  152. /* page load function
  153. document.addEventListener('yt-service-request-sent', e => {
  154. // console.log('loaded', e)
  155. });
  156. */