Greasy Fork 还支持 简体中文。

Google Video Playback Optimizer

Keep Google video playback active even when the tab is not in focus

  1. // ==UserScript==
  2. // @name Google Video Playback Optimizer
  3. // @namespace http://tampermonkey.net/
  4. // @version 2024-10-09
  5. // @description Keep Google video playback active even when the tab is not in focus
  6. // @author UniverseDev
  7. // @license GPL-3.0-or-later
  8. // @match https://www.google.com/search?*
  9. // @icon https://www.google.com/s2/favicons?domain=google.com&sz=64
  10. // @grant none
  11. // ==/UserScript==
  12.  
  13. (function() {
  14. 'use strict';
  15.  
  16. function keepPageVisible() {
  17. let hidden;
  18. if (typeof document.hidden !== "undefined") {
  19. hidden = "hidden";
  20. } else if (typeof document.msHidden !== "undefined") {
  21. hidden = "msHidden";
  22. } else if (typeof document.webkitHidden !== "undefined") {
  23. hidden = "webkitHidden";
  24. } else {
  25. console.warn('Google Video Playback Optimizer: Visibility API not supported');
  26. return;
  27. }
  28.  
  29. try {
  30. Object.defineProperty(document, hidden, {
  31. get: () => false,
  32. configurable: true
  33. });
  34.  
  35. Object.defineProperty(document, 'visibilityState', {
  36. get: () => 'visible',
  37. configurable: true
  38. });
  39.  
  40. console.log('Google Video Playback Optimizer: Page visibility override applied');
  41. } catch (error) {
  42. console.error('Google Video Playback Optimizer: Failed to override visibility properties', error);
  43. }
  44. }
  45.  
  46. function checkAndActivateForVideo() {
  47. const videoElements = document.querySelectorAll('video');
  48. if (videoElements.length > 0) {
  49. keepPageVisible();
  50. }
  51. }
  52.  
  53. function checkAndActivateVisibilityOverride() {
  54. const url = window.location.href;
  55. const fragment = window.location.hash;
  56.  
  57. if (fragment.includes('vid:')) {
  58. keepPageVisible();
  59. } else {
  60. console.log('Google Video Playback Optimizer: Not a video page based on URL fragment.');
  61. }
  62. }
  63.  
  64. setInterval(checkAndActivateForVideo, 2000);
  65.  
  66. window.addEventListener('load', () => {
  67. checkAndActivateForVideo();
  68. checkAndActivateVisibilityOverride();
  69. });
  70.  
  71. const originalPushState = history.pushState;
  72. const originalReplaceState = history.replaceState;
  73.  
  74. history.pushState = function() {
  75. originalPushState.apply(this, arguments);
  76. checkAndActivateForVideo();
  77. checkAndActivateVisibilityOverride();
  78. };
  79.  
  80. history.replaceState = function() {
  81. originalReplaceState.apply(this, arguments);
  82. checkAndActivateForVideo();
  83. checkAndActivateVisibilityOverride();
  84. };
  85.  
  86. checkAndActivateForVideo();
  87. checkAndActivateVisibilityOverride();
  88.  
  89. })();