Youtube Player Controls below Video

Move YouTube Player Controls below the video

当前为 2023-06-29 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Youtube Player Controls below Video
  3. // @description Move YouTube Player Controls below the video
  4. // @namespace Userscript
  5. // @version 0.1.4
  6. // @match https://www.youtube.com/*
  7. // @grant none
  8. // @noframes
  9. // @author CY Fung
  10. // @license MIT
  11. // @run-at document-start
  12. // ==/UserScript==
  13.  
  14. (() => {
  15. const SCRIPT_CLASSNAME = 'yt8447-enabled'
  16. const SCRIPT_CSS_ID = 'fj74F'
  17.  
  18. const css_text = `
  19. .${SCRIPT_CLASSNAME} {
  20. --yt8448-gap: max(58px, var(--subs-gap, 0px));
  21. --yt8448-gap-theater: max(58px, var(--subs-gap-theater, 0px));
  22. --yt8447-height: 52px;
  23. --yt8447-black-background: block;
  24. }
  25.  
  26. .${SCRIPT_CLASSNAME} ytd-player#ytd-player .ytp-chrome-bottom {
  27. bottom: calc( var(--yt8447-height) * -1 );
  28. }
  29.  
  30. .${SCRIPT_CLASSNAME} ytd-player#ytd-player .ytp-chrome-bottom::before {
  31. position: absolute;
  32. left: -12px;
  33. right: -12px;
  34. content: '';
  35. display: var(--yt8447-black-background, none);
  36. bottom: -6px;
  37. top: -6px;
  38. background-color: black;
  39. z-index: -1;
  40. transform: translateZ(-1px);
  41. }
  42.  
  43. html[dark][darker-dark-theme] ytd-watch-flexy.style-scope[cinematics-enabled].${SCRIPT_CLASSNAME} {
  44. --yt8447-black-background: none;
  45. }
  46.  
  47. .${SCRIPT_CLASSNAME} ytd-player#ytd-player #movie_player::after {
  48. position: absolute;
  49. display: block;
  50. content: '';
  51. left: 0;
  52. right: 0;
  53. height: var(--yt8447-height);
  54. bottom: calc( var(--yt8447-height) * -1 );
  55. opacity: 0 !important;
  56. pointer-events: auto !important;
  57. }
  58.  
  59. .${SCRIPT_CLASSNAME} ytd-player#ytd-player #movie_player {
  60. overflow: visible;
  61. z-index: 999;
  62. }
  63.  
  64. .${SCRIPT_CLASSNAME} #columns.ytd-watch-flexy {
  65. --subs-gap: var(--yt8448-gap);
  66. --subs-gap-theater: var(--yt8448-gap-theater);
  67. }
  68.  
  69. .${SCRIPT_CLASSNAME}[theater]:not([fullscreen]) #below.ytd-watch-flexy, .${SCRIPT_CLASSNAME}[theater]:not([fullscreen]) #secondary.ytd-watch-flexy {
  70. --yt8448-gap: var(--yt8448-gap-theater);
  71. }
  72.  
  73. .${SCRIPT_CLASSNAME} #below.ytd-watch-flexy, .${SCRIPT_CLASSNAME}[theater]:not([fullscreen]) #secondary.ytd-watch-flexy {
  74. margin-top: var(--yt8448-gap) !important;
  75. transition: margin-top 0.25s;
  76. }
  77.  
  78. `
  79.  
  80. function isItVideoPage() {
  81. return window.location.href.includes('/watch?v=');
  82. }
  83.  
  84. let mState = 0;
  85. function main(evt) {
  86.  
  87. if (mState === 0) {
  88. if (document.getElementById(SCRIPT_CSS_ID)) {
  89. mState = -1;
  90. console.warn('yt8447: duplicated script');
  91. return;
  92. }
  93. const style = document.createElement('style');
  94. style.textContent = css_text;
  95. style.id = SCRIPT_CSS_ID;
  96. document.head.appendChild(style);
  97. } else if (mState < 0) {
  98. return;
  99. }
  100. if (evt.type === 'yt-page-data-updated') {
  101. mState = 1;
  102. } else if (mState === 0) {
  103. mState = 2;
  104. } else if (mState >= 1) {
  105. return;
  106. }
  107.  
  108. const playerElt = document.querySelector('ytd-watch-flexy');
  109. if (playerElt !== null) {
  110. if (isItVideoPage()) {
  111. playerElt.classList.add(SCRIPT_CLASSNAME);
  112. } else {
  113. playerElt.classList.remove(SCRIPT_CLASSNAME);
  114. }
  115. }
  116.  
  117. }
  118.  
  119. document.addEventListener('yt-navigate-finish', main);
  120. document.addEventListener('yt-page-data-fetched', main);
  121. })();