您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Enhances your video by applying filter to it with a control panel and additional features.
- // ==UserScript==
- // @name Video Enhancer with Advanced Control Panel
- // @namespace http://tampermonkey.net/
- // @version 1.4
- // @author UMATTER
- // @description Enhances your video by applying filter to it with a control panel and additional features.
- // @match *://*/*
- // @grant GM_getValue
- // @grant GM_setValue
- // @grant GM_addStyle
- // @grant GM_registerMenuCommand
- // @license MIT
- // ==/UserScript==
- (function() {
- 'use strict';
- // SVG Filters
- const svgFilters = `
- <svg id="svgfilters" aria-hidden="true" style="position: absolute; width: 0; height: 0; overflow: hidden;" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
- <defs>
- <filter id="none"></filter>
- <filter id="turbulence">
- <feTurbulence type="fractalNoise" baseFrequency="0.015" numOctaves="2" result="turbulence_3" data-filterId="3" />
- <feDisplacementMap xChannelSelector="R" yChannelSelector="G" in="SourceGraphic" in2="turbulence_3" scale="25" />
- </filter>
- <filter id="squiggly">
- <feTurbulence id="turbulence1" baseFrequency="0.02" numOctaves="3" result="noise" seed="0" />
- <feDisplacementMap id="displacement" in="SourceGraphic" in2="noise" scale="6" />
- </filter>
- <filter id="squiggly-1">
- <feTurbulence id="turbulence2" baseFrequency="0.02" numOctaves="3" result="noise" seed="1" />
- <feDisplacementMap in="SourceGraphic" in2="noise" scale="8" />
- </filter>
- <filter id="squiggly-2">
- <feTurbulence id="turbulence3" baseFrequency="0.02" numOctaves="3" result="noise" seed="2" />
- <feDisplacementMap in="SourceGraphic" in2="noise" scale="6" />
- </filter>
- <filter id="squiggly-3">
- <feTurbulence id="turbulence4" baseFrequency="0.02" numOctaves="3" result="noise" seed="3" />
- <feDisplacementMap in="SourceGraphic" in2="noise" scale="8" />
- </filter>
- <filter id="squiggly-4">
- <feTurbulence id="turbulence5" baseFrequency="0.02" numOctaves="3" result="noise" seed="4" />
- <feDisplacementMap in="SourceGraphic" in2="noise" scale="6" />
- </filter>
- </defs>
- </svg>
- `;
- document.body.insertAdjacentHTML('beforeend', svgFilters);
- // Initialization
- const htmlElement = window.document.documentElement;
- let defaultEnhancerActive = GM_getValue('defaultEnhancerActive', false);
- let saturateValue = GM_getValue('saturateValue', 1.3);
- let brightnessValue = GM_getValue('brightnessValue', 1);
- let contrastValue = GM_getValue('contrastValue', 1);
- function setFilterOnElement(element) {
- if (defaultEnhancerActive) {
- element.style.filter = `saturate(${saturateValue}) brightness(${brightnessValue}) contrast(${contrastValue})`;
- } else {
- element.style.filter = "none";
- }
- }
- function toggleEnhancer() {
- defaultEnhancerActive = !defaultEnhancerActive;
- GM_setValue('defaultEnhancerActive', defaultEnhancerActive);
- setFilterOnElement(htmlElement);
- if (fullscreenElement) {
- setFilterOnElement(fullscreenElement);
- }
- alert(`Video Enhancer is now ${defaultEnhancerActive ? 'ON' : 'OFF'}`);
- }
- function createControlPanel() {
- const controlPanel = document.createElement('div');
- controlPanel.style.position = 'fixed';
- controlPanel.style.bottom = '10px';
- controlPanel.style.right = '10px';
- controlPanel.style.backgroundColor = 'rgba(0, 0, 0, 0.8)';
- controlPanel.style.color = 'white';
- controlPanel.style.padding = '10px';
- controlPanel.style.borderRadius = '5px';
- controlPanel.style.zIndex = '10000';
- controlPanel.innerHTML = `
- <button id="toggleEnhancerBtn">Toggle Enhancer</button>
- <br/>
- <label>Saturate: <input type="range" id="saturateRange" min="1" max="3" step="0.1" value="${saturateValue}"><input type="number" id="saturateNumber" min="1" max="3" step="0.1" value="${saturateValue}" style="width: 50px; margin-left: 10px;"></label>
- <br/>
- <label>Brightness: <input type="range" id="brightnessRange" min="0.5" max="2" step="0.1" value="${brightnessValue}"><input type="number" id="brightnessNumber" min="0.5" max="2" step="0.1" value="${brightnessValue}" style="width: 50px; margin-left: 10px;"></label>
- <br/>
- <label>Contrast: <input type="range" id="contrastRange" min="0.5" max="2" step="0.1" value="${contrastValue}"><input type="number" id="contrastNumber" min="0.5" max="2" step="0.1" value="${contrastValue}" style="width: 50px; margin-left: 10px;"></label>
- <br/>
- <button id="exportPresetBtn">Export Preset</button>
- <button id="importPresetBtn">Import Preset</button>
- <input type="file" id="presetFileInput" style="display: none;">
- `;
- document.body.appendChild(controlPanel);
- document.getElementById('toggleEnhancerBtn').addEventListener('click', toggleEnhancer);
- const saturateRange = document.getElementById('saturateRange');
- const saturateNumber = document.getElementById('saturateNumber');
- saturateRange.addEventListener('input', (e) => {
- saturateValue = e.target.value;
- saturateNumber.value = saturateValue;
- GM_setValue('saturateValue', saturateValue);
- if (defaultEnhancerActive) {
- setFilterOnElement(htmlElement);
- if (fullscreenElement) {
- setFilterOnElement(fullscreenElement);
- }
- }
- });
- saturateNumber.addEventListener('input', (e) => {
- saturateValue = e.target.value;
- saturateRange.value = saturateValue;
- GM_setValue('saturateValue', saturateValue);
- if (defaultEnhancerActive) {
- setFilterOnElement(htmlElement);
- if (fullscreenElement) {
- setFilterOnElement(fullscreenElement);
- }
- }
- });
- const brightnessRange = document.getElementById('brightnessRange');
- const brightnessNumber = document.getElementById('brightnessNumber');
- brightnessRange.addEventListener('input', (e) => {
- brightnessValue = e.target.value;
- brightnessNumber.value = brightnessValue;
- GM_setValue('brightnessValue', brightnessValue);
- if (defaultEnhancerActive) {
- setFilterOnElement(htmlElement);
- if (fullscreenElement) {
- setFilterOnElement(fullscreenElement);
- }
- }
- });
- brightnessNumber.addEventListener('input', (e) => {
- brightnessValue = e.target.value;
- brightnessRange.value = brightnessValue;
- GM_setValue('brightnessValue', brightnessValue);
- if (defaultEnhancerActive) {
- setFilterOnElement(htmlElement);
- if (fullscreenElement) {
- setFilterOnElement(fullscreenElement);
- }
- }
- });
- const contrastRange = document.getElementById('contrastRange');
- const contrastNumber = document.getElementById('contrastNumber');
- contrastRange.addEventListener('input', (e) => {
- contrastValue = e.target.value;
- contrastNumber.value = contrastValue;
- GM_setValue('contrastValue', contrastValue);
- if (defaultEnhancerActive) {
- setFilterOnElement(htmlElement);
- if (fullscreenElement) {
- setFilterOnElement(fullscreenElement);
- }
- }
- });
- contrastNumber.addEventListener('input', (e) => {
- contrastValue = e.target.value;
- contrastRange.value = contrastValue;
- GM_setValue('contrastValue', contrastValue);
- if (defaultEnhancerActive) {
- setFilterOnElement(htmlElement);
- if (fullscreenElement) {
- setFilterOnElement(fullscreenElement);
- }
- }
- });
- document.getElementById('exportPresetBtn').addEventListener('click', () => {
- const preset = {
- saturateValue: saturateValue,
- brightnessValue: brightnessValue,
- contrastValue: contrastValue,
- };
- const blob = new Blob([JSON.stringify(preset)], {type: "application/json"});
- const url = URL.createObjectURL(blob);
- const a = document.createElement('a');
- a.href = url;
- a.download = 'preset.json';
- document.body.appendChild(a);
- a.click();
- document.body.removeChild(a);
- URL.revokeObjectURL(url);
- });
- document.getElementById('importPresetBtn').addEventListener('click', () => {
- document.getElementById('presetFileInput').click();
- });
- document.getElementById('presetFileInput').addEventListener('change', (e) => {
- const file = e.target.files[0];
- if (file) {
- const reader = new FileReader();
- reader.onload = (event) => {
- const preset = JSON.parse(event.target.result);
- saturateValue = preset.saturateValue || saturateValue;
- brightnessValue = preset.brightnessValue || brightnessValue;
- contrastValue = preset.contrastValue || contrastValue;
- GM_setValue('saturateValue', saturateValue);
- GM_setValue('brightnessValue', brightnessValue);
- GM_setValue('contrastValue', contrastValue);
- saturateRange.value = saturateValue;
- saturateNumber.value = saturateValue;
- brightnessRange.value = brightnessValue;
- brightnessNumber.value = brightnessValue;
- contrastRange.value = contrastValue;
- contrastNumber.value = contrastValue;
- setFilterOnElement(htmlElement);
- if (fullscreenElement) {
- setFilterOnElement(fullscreenElement);
- }
- };
- reader.readAsText(file);
- }
- });
- }
- createControlPanel();
- // Applying filters to full screen elements like video
- let fullscreenElement = null;
- document.onfullscreenchange = () => {
- let currentFullScreenElement = document.fullscreenElement;
- if (currentFullScreenElement) {
- if (currentFullScreenElement.tagName == "HTML") {
- return;
- }
- fullscreenElement = currentFullScreenElement;
- setFilterOnElement(fullscreenElement);
- } else {
- if (fullscreenElement) {
- fullscreenElement.style.filter = "none";
- fullscreenElement = null;
- }
- }
- };
- // Listen for storage changes
- window.addEventListener('storage', function(e) {
- if (e.key === 'defaultEnhancerActive') {
- defaultEnhancerActive = GM_getValue('defaultEnhancerActive', false);
- setFilterOnElement(htmlElement);
- }
- });
- // Keyboard shortcut
- document.addEventListener('keydown', (e) => {
- if (e.key === 'E' && e.ctrlKey) {
- toggleEnhancer();
- }
- });
- // Apply filter on initial load
- setFilterOnElement(htmlElement);
- })();