Auto Orientation Fullscreen

Adjusts screen orientation to match video aspect ratio in fullscreen for android browser.

  1. // ==UserScript==
  2. // @name Auto Orientation Fullscreen
  3. // @namespace https://github.com/ImPeekaboo
  4. // @version 1.0
  5. // @author Ayam Penyet
  6. // @description Adjusts screen orientation to match video aspect ratio in fullscreen for android browser.
  7. // @homepageURL https://github.com/ImPeekaboo/auto-rotate-fullscreen
  8. // @supportURL https://github.com/ImPeekaboo/auto-rotate-fullscreen/issues
  9. // @icon https://cdn-icons-png.flaticon.com/512/10023/10023275.png
  10. // @grant none
  11. // @match *://*/*
  12. // ==/UserScript==
  13.  
  14. (function() {
  15. 'use strict';
  16.  
  17. let orientationLocked = false;
  18.  
  19. // Function to check if the video is landscape
  20. function isLandscape(video) {
  21. return video.videoWidth > video.videoHeight;
  22. }
  23.  
  24. // Function to check if the video player is a native video player
  25. function isNativeVideoPlayer(videoElement) {
  26. if (videoElement && videoElement instanceof HTMLVideoElement) {
  27. const hasNativeControls = videoElement.controls === true;
  28. const hasSource = videoElement.querySelector('source') !== null;
  29. const hasWidthHeight = videoElement.clientWidth > 0 && videoElement.clientHeight > 0;
  30.  
  31. // If the video has controls and width/height set, it's likely a native player
  32. return hasNativeControls && hasSource && hasWidthHeight;
  33. }
  34. return false; // Not a native player
  35. }
  36.  
  37. // Lock or unlock screen orientation
  38. function setOrientation(video) {
  39. if (isNativeVideoPlayer(video)) {
  40. return; // Do not adjust orientation for native video players
  41. }
  42.  
  43. if (screen.orientation) {
  44. const desiredOrientation = isLandscape(video) ? "landscape" : "portrait";
  45. if (orientationLocked && screen.orientation.locked !== desiredOrientation) {
  46. screen.orientation.lock(desiredOrientation).catch(console.warn);
  47. } else if (!orientationLocked) {
  48. screen.orientation.lock(desiredOrientation).then(() => {
  49. orientationLocked = true;
  50. }).catch(console.warn);
  51. }
  52. }
  53. }
  54.  
  55. // Unlock orientation when exiting fullscreen
  56. function unlockOrientation() {
  57. if (screen.orientation && orientationLocked) {
  58. screen.orientation.unlock().then(() => {
  59. orientationLocked = false;
  60. }).catch(console.warn);
  61. }
  62. }
  63.  
  64. // Get the video element, including from shadow DOM and iframes
  65. function getVideoElement() {
  66. const fullscreenElem = document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement;
  67. if (!fullscreenElem) return null;
  68.  
  69. // Try to get video directly
  70. let video = fullscreenElem.querySelector('video');
  71. if (video) return video;
  72.  
  73. // Check shadow DOM
  74. if (fullscreenElem.shadowRoot) {
  75. video = fullscreenElem.shadowRoot.querySelector('video');
  76. if (video) return video;
  77. }
  78.  
  79. // Check iframes
  80. const iframes = document.querySelectorAll('iframe');
  81. for (const iframe of iframes) {
  82. try {
  83. const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
  84. video = iframeDoc.querySelector('video');
  85. if (video && iframeDoc.fullscreenElement) return video;
  86. } catch (e) {
  87. console.warn("Cross-origin iframe:", e);
  88. }
  89. }
  90.  
  91. return null;
  92. }
  93.  
  94. // Handle orientation when entering fullscreen
  95. function handleFullscreenChange() {
  96. const video = getVideoElement();
  97. if (video) {
  98. // Check and set orientation on entering fullscreen
  99. setOrientation(video);
  100. video.addEventListener('loadedmetadata', () => setOrientation(video), { once: true });
  101. video.addEventListener('play', () => setOrientation(video));
  102. } else {
  103. unlockOrientation(); // Unlock orientation when exiting fullscreen
  104. }
  105. }
  106.  
  107. // Setup fullscreen event listeners
  108. document.addEventListener('fullscreenchange', handleFullscreenChange);
  109. document.addEventListener('webkitfullscreenchange', handleFullscreenChange);
  110. document.addEventListener('mozfullscreenchange', handleFullscreenChange);
  111.  
  112. // Check for initial videos on page load
  113. const observer = new MutationObserver(() => {
  114. document.querySelectorAll('video:not([data-script-processed])').forEach(video => {
  115. video.setAttribute('data-script-processed', true);
  116. video.addEventListener('loadedmetadata', () => setOrientation(video), { once: true });
  117. video.addEventListener('play', () => setOrientation(video));
  118. });
  119. });
  120. observer.observe(document, { childList: true, subtree: true });
  121. })();