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.1
  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. }
  24.  
  25. .${SCRIPT_CLASSNAME} ytd-player#ytd-player .ytp-chrome-bottom {
  26. bottom: calc( var(--yt8447-height) * -1 );
  27. }
  28.  
  29. .${SCRIPT_CLASSNAME} ytd-player#ytd-player #movie_player::after {
  30. position: absolute;
  31. display: block;
  32. content: '';
  33. left: 0;
  34. right: 0;
  35. height: var(--yt8447-height);
  36. bottom: calc( var(--yt8447-height) * -1 );
  37. opacity: 0 !important;
  38. pointer-events: auto !important;
  39. }
  40.  
  41. .${SCRIPT_CLASSNAME} ytd-player#ytd-player #movie_player {
  42. overflow: visible;
  43. z-index: 999;
  44. }
  45.  
  46. .${SCRIPT_CLASSNAME} #columns.ytd-watch-flexy {
  47. --subs-gap: var(--yt8448-gap);
  48. --subs-gap-theater: var(--yt8448-gap-theater);
  49. }
  50.  
  51. .${SCRIPT_CLASSNAME}[theater]:not([fullscreen]) #below.ytd-watch-flexy, .${SCRIPT_CLASSNAME}[theater]:not([fullscreen]) #secondary.ytd-watch-flexy {
  52. --yt8448-gap: var(--yt8448-gap-theater);
  53. }
  54.  
  55. .${SCRIPT_CLASSNAME} #below.ytd-watch-flexy, .${SCRIPT_CLASSNAME}[theater]:not([fullscreen]) #secondary.ytd-watch-flexy {
  56. margin-top: var(--yt8448-gap) !important;
  57. transition: margin-top 0.25s;
  58. }
  59.  
  60. `
  61.  
  62. function isItVideoPage() {
  63. return window.location.href.includes('/watch?v=');
  64. }
  65.  
  66. let mState = 0;
  67. function main(evt) {
  68.  
  69. if (mState === 0) {
  70. if (document.getElementById(SCRIPT_CSS_ID)) {
  71. mState = -1;
  72. console.warn('yt8447: duplicated script');
  73. return;
  74. }
  75. const style = document.createElement('style');
  76. style.textContent = css_text;
  77. style.id = SCRIPT_CSS_ID;
  78. document.head.appendChild(style);
  79. } else if (mState < 0) {
  80. return;
  81. }
  82. if (evt.type === 'yt-page-data-updated') {
  83. mState = 1;
  84. } else if (mState === 0) {
  85. mState = 2;
  86. } else if (mState >= 1) {
  87. return;
  88. }
  89.  
  90. const playerElt = document.querySelector('ytd-watch-flexy');
  91. if (playerElt !== null) {
  92. if (isItVideoPage()) {
  93. playerElt.classList.add(SCRIPT_CLASSNAME);
  94. } else {
  95. playerElt.classList.remove(SCRIPT_CLASSNAME);
  96. }
  97. }
  98.  
  99. }
  100.  
  101. document.addEventListener('yt-navigate-finish', main);
  102. document.addEventListener('yt-page-data-fetched', main);
  103. })();