Fullscreen Button for fishtank.live

Adds a fullscreen button to the fishtank.live video player.

  1. // ==UserScript==
  2. // @name Fullscreen Button for fishtank.live
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.1
  5. // @description Adds a fullscreen button to the fishtank.live video player.
  6. // @author Flowscript
  7. // @match https://www.fishtank.live/*
  8. // @license MIT
  9. // @grant none
  10. // ==/UserScript==
  11.  
  12. (function() {
  13. 'use strict';
  14.  
  15. const videoSelectors = [
  16. '.livepeer-video-player_livepeer-video-player__NRXYi',
  17. '.livepeer-video-player_livepeer-video-player__NRXYi'
  18. ];
  19.  
  20. const videoSelector = '#livepeer-video-player video';
  21. const controlsContainerSelector = '.livepeer-video-player_controls__y36El';
  22.  
  23. function toggleFullscreen(videoContainer, video) {
  24. if (!document.fullscreenElement) {
  25. videoContainer.requestFullscreen().then(() => {
  26. video.play(); // Ensure the video continues playing when entering fullscreen
  27. }).catch(err => {
  28. console.error(`Error attempting to enable full-screen mode: ${err.message} (${err.name})`);
  29. });
  30. } else {
  31. document.exitFullscreen().then(() => {
  32. video.play(); // Ensure the video continues playing when exiting fullscreen
  33. });
  34. }
  35. }
  36.  
  37. function addFullscreenButton(videoContainer, video, controlsContainer) {
  38. // Check if fullscreen button already exists to avoid duplicates
  39. if (controlsContainer.querySelector('.custom-fullscreen-button')) {
  40. return;
  41. }
  42.  
  43. // Create fullscreen button
  44. const fullscreenButton = document.createElement('button');
  45. fullscreenButton.className = 'custom-fullscreen-button';
  46. fullscreenButton.innerHTML = `<div class="icon_icon__bDzMA"><svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M8 4v2H4v4H2V4a2 2 0 012-2h6v2H8zm8 0V2h6a2 2 0 012 2v6h-2V6h-4V4h-2zm0 16h2v-2h4v-4h2v6a2 2 0 01-2 2h-6v-2zM4 14H2v6a2 2 0 002 2h6v-2H4v-4H2v-2z" fill="currentColor"></path></svg></div>`;
  47. fullscreenButton.style.all = 'unset';
  48. fullscreenButton.style.cursor = 'pointer';
  49. fullscreenButton.style.display = 'flex';
  50. fullscreenButton.style.alignItems = 'center';
  51. fullscreenButton.style.justifyContent = 'center';
  52. fullscreenButton.style.backgroundColor = 'rgba(0, 0, 0, 0.5)';
  53. fullscreenButton.style.padding = '4px';
  54. fullscreenButton.style.height = '25px';
  55. fullscreenButton.style.width = '25px';
  56. fullscreenButton.style.color = '#fff';
  57. fullscreenButton.style.pointerEvents = 'auto';
  58. fullscreenButton.style.position = 'absolute';
  59. fullscreenButton.style.bottom = '5px';
  60. fullscreenButton.style.right = '15px';
  61. fullscreenButton.style.zIndex = '1000';
  62. fullscreenButton.title = 'Fullscreen';
  63.  
  64. // Add hover effect
  65. fullscreenButton.addEventListener('mouseenter', () => {
  66. fullscreenButton.style.color = '#f8ec94';
  67. });
  68.  
  69. fullscreenButton.addEventListener('mouseleave', () => {
  70. fullscreenButton.style.color = '#fff';
  71. });
  72.  
  73. fullscreenButton.addEventListener('click', () => {
  74. toggleFullscreen(videoContainer, video);
  75. });
  76.  
  77. // Add the button to the controls container
  78. controlsContainer.appendChild(fullscreenButton);
  79. }
  80.  
  81. function addCustomCSS() {
  82. // Check if the custom style already exists
  83. if (!document.querySelector('#custom-livepeer-style')) {
  84. const style = document.createElement('style');
  85. style.id = 'custom-livepeer-style';
  86. style.innerHTML = `
  87. div[class*="live-stream-clipping_live-stream-clipping__"] {
  88. margin-bottom: 25px;
  89. }
  90. `;
  91. document.head.appendChild(style);
  92. }
  93. }
  94.  
  95. function applyChanges() {
  96. videoSelectors.forEach(selector => {
  97. const videoContainer = document.querySelector(selector);
  98. const video = document.querySelector(videoSelector);
  99. const controlsContainer = document.querySelector(controlsContainerSelector);
  100.  
  101. if (videoContainer && controlsContainer) {
  102. addFullscreenButton(videoContainer, video, controlsContainer);
  103. addCustomCSS();
  104. }
  105. });
  106. }
  107.  
  108. function handleKeydown(event) {
  109. const activeElement = document.activeElement;
  110. const isInputFocused = activeElement.tagName === 'INPUT' ||
  111. activeElement.tagName === 'TEXTAREA' ||
  112. activeElement.isContentEditable;
  113.  
  114. if (!isInputFocused && (event.key === 'f' || event.key === 'F')) {
  115. videoSelectors.forEach(selector => {
  116. const videoContainer = document.querySelector(selector);
  117. const video = document.querySelector(videoSelector);
  118.  
  119. if (videoContainer && video) {
  120. toggleFullscreen(videoContainer, video);
  121. }
  122. });
  123. }
  124. }
  125.  
  126. document.addEventListener('keydown', handleKeydown);
  127.  
  128. // Use MutationObserver to detect changes in the DOM
  129. const observer = new MutationObserver(applyChanges);
  130. observer.observe(document.body, { childList: true, subtree: true });
  131.  
  132. // Initial application
  133. applyChanges();
  134.  
  135. })();