Universal Video Sharpener (CSS Filter)

Applies video sharpening using CSS filters across websites

  1. // ==UserScript==
  2. // @name Universal Video Sharpener (CSS Filter)
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.3
  5. // @description Applies video sharpening using CSS filters across websites
  6. // @match *://*/*
  7. // @grant GM_setValue
  8. // @grant GM_getValue
  9. // @grant GM_registerMenuCommand
  10. // @grant GM_notification
  11. // @license MIT
  12. // ==/UserScript==
  13.  
  14. (function() {
  15. 'use strict';
  16. // Configuration
  17. const CONFIG = {
  18. contrast: 1.1,
  19. brightness: 1.2,
  20. saturate: 1.1,
  21. debugMode: false
  22. };
  23.  
  24. // Logging function
  25. function log(message) {
  26. if (CONFIG.debugMode) {
  27. console.log(`[Video Sharpener] ${message}`);
  28. }
  29. }
  30.  
  31. // Detect if an element is likely a video
  32. function isVideoElement(element) {
  33. return element instanceof HTMLVideoElement &&
  34. element.videoWidth > 0 &&
  35. element.videoHeight > 0;
  36. }
  37.  
  38. // Apply CSS sharpness filter
  39. function applySharpnessFilter(video, isEnabled) {
  40. if (!video) return;
  41. try {
  42. if (isEnabled) {
  43. const { contrast, brightness, saturate } = CONFIG;
  44. video.style.filter = `
  45. contrast(${contrast})
  46. brightness(${brightness})
  47. saturate(${saturate})
  48. `;
  49. video.dataset.sharpened = 'true';
  50. log('CSS Sharpness filter applied');
  51. } else {
  52. video.style.filter = 'none';
  53. delete video.dataset.sharpened;
  54. log('Sharpness filter removed');
  55. }
  56. } catch (error) {
  57. console.error('Error applying sharpness filter:', error);
  58. }
  59. }
  60.  
  61. // Update all videos on the page
  62. function updateAllVideos(isEnabled) {
  63. const videos = document.querySelectorAll('video');
  64. videos.forEach(video => {
  65. if (isVideoElement(video)) {
  66. applySharpnessFilter(video, isEnabled);
  67. }
  68. });
  69. }
  70.  
  71. // Main processing function
  72. function processVideos() {
  73. const isScriptEnabled = GM_getValue('universalSharpenerEnabled', false);
  74. const videos = document.querySelectorAll('video:not([data-sharpened])');
  75. videos.forEach(video => {
  76. if (isVideoElement(video)) {
  77. applySharpnessFilter(video, isScriptEnabled);
  78. }
  79. });
  80. }
  81.  
  82. // Toggle function with notification
  83. function toggleSharpener() {
  84. const currentState = GM_getValue('universalSharpenerEnabled', false);
  85. const newState = !currentState;
  86. GM_setValue('universalSharpenerEnabled', newState);
  87.  
  88. // Update all existing videos
  89. updateAllVideos(newState);
  90.  
  91. // Show notification
  92. GM_notification({
  93. text: `Video Sharpener: ${newState ? 'Enabled' : 'Disabled'}`,
  94. timeout: 2000,
  95. title: 'Video Sharpener'
  96. });
  97. }
  98.  
  99. // Initialize script
  100. function initScript() {
  101. // Get initial state
  102. const isEnabled = GM_getValue('universalSharpenerEnabled', false);
  103.  
  104. // Register menu command with state indicator
  105. GM_registerMenuCommand(
  106. `${isEnabled ? '✓' : '✗'} Toggle Video Sharpener`,
  107. toggleSharpener
  108. );
  109.  
  110. // Use MutationObserver for dynamic content
  111. const observer = new MutationObserver(() => {
  112. processVideos();
  113. });
  114.  
  115. // Observe the entire document for changes
  116. observer.observe(document.body, {
  117. childList: true,
  118. subtree: true
  119. });
  120.  
  121. // Initial processing and periodic check
  122. processVideos();
  123. setInterval(processVideos, 3000);
  124. }
  125.  
  126. // Start script
  127. initScript();
  128. })();