Greasy Fork is available in English.

Youtube Video Filters

Ehance Youtube video player with filters (see "FX" button near "Fullscreen")


Installer ce script?
// ==UserScript==// @name 		Youtube Video Filters// @author 		Xavier Bouhours// @version 		2024-05-25// @description     	Ehance Youtube video player with filters (see "FX" button near "Fullscreen")// @description:fr 	Ajout de filtres vidéos au player. La propriété css filter est exploitée pour le rendu.// @description:en 	Luminosity and contrast for Youtube site player.// @run-at       	document-end// @compatible 		firefox// @license		MIT// @homepage 		https://gfork.dahi.icu/fr/scripts/495951-youtube-video-filters// @match        	https://*.youtube.com/*// @namespace https://greasyfork.org/users/1306337// ==/UserScript==(function(W,D,undefined){const V = W.videoFx ={// On récupère le player html5 de Youtubevideo 	: D.querySelector("video.html5-main-video"),controls: D.querySelector(".ytp-right-controls"),// On crée le bouton d'appel de la fenêtre des filtresfx 		: D.createElement("button"),// On crée le panneau de manipulation des filtrespanel 	: D.createElement("div"),header	: D.createElement("header"),// On crée le set de boutonsclose 	: D.createElement("button"),fxswitch: D.createElement("input"),// Filters store : On initialise les filtresfilters :{brightness	: { min:0, val:100, max:200, unit:"%", step: 1 },contrast	: { min:0, val:100, max:200, unit:"%", step: 1 },saturate	: { min:0, val:100, max:300, unit:"%", step: 1 },grayscale	: { min:0, val:0, max:100, unit:"%", step: 1 },'hue-rotate': { min:-360, val:0, max:360, unit:"deg", step: 1 },invert		: { min:0, val:0, max:100, unit:"%", step: 1 },sepia		: { min:0, val:0, max:100, unit:"%", step: 1 },blur		: { min:0, val:0, max:10, unit:"px", step: 1 }},// Application des filtres à la vidéorefresh : function(){var k, c = "";// On compile chaque filtre pour la propriété cssfor( k in V.filters ){var f = V.filters[k];c+= k+'('+ f.val + f.unit +') ';};// On applique le style à la vidéoV.video.style.filter = c ;// console.log(c);},// Ajouter un réglage de filtre au panneau// @see: https://blog.hubspot.com/website/html-slider// @ex: <input type='range' min='0' value='1' max='3' name='contrast'>addfilter : function( name, min, val, max ){letC = D.createElement("div"), 	// ConteneurI = D.createElement("input"),	// SliderL = D.createElement("label");	// TitreI.type 	= "range";I.name 	= I.title = I.style.content = name;I.min 	= min;I.value	= val;I.max	= max;// On ajoute le conteneur pour le label et le curseurV.panel.append(C);// On ajoute le titreC.append(L);L.append(name);//… et le curseur de réglageC.append(I);I.addEventListener("change", function(){// On sauvegarde la valeur// console.log(this,I);V.filters[I.name].val = I.value ;// On applique les modificationsV.refresh();});},initialized : false,// Initialisation du moduleinit	: function(){if(!!V.initialized) return true ;// On ajoute le bouton "FX" aux contrôles du playerV.controls.append(V.fx);V.fx.classList.add("ytp-button");V.fx.classList.add("video-fx");V.fx.append("FX");V.fx.addEventListener("click", () =>{V.panel.classList.remove(V.panel.classList.item(1)); // item(0) = "video-filters" ; item(1) = "hidden"});// On ajoute le panneau des filtres…// V.controls.append(V.panel);D.querySelector("body").append(V.panel);V.panel.classList.add("video-filters");V.panel.classList.add("hidden");// … avec son header (draggable zone)V.panel.append(V.header);V.header.append("Video Filters");// … avec ses filtres,var n ;for( n in V.filters ){var f = V.filters[n];V.addfilter( n, f.min, f.val, f.max, f.step );};// … et son bouton de fermetureV.header.append(V.close);V.close.append("X");V.close.setAttribute("title","Close");V.close.classList.add("close");V.close.addEventListener("click", () =>{V.panel.classList.add("hidden");});// … et le bouton switch dpour la désactivation des filtresV.header.append(V.fxswitch);V.fxswitch.classList.add("switch");V.fxswitch.setAttribute("type","checkbox");V.fxswitch.setAttribute("checked","true");V.fxswitch.addEventListener("click", () =>{// set Onif( V.fxswitch.checked == 1 ){V.refresh();V.panel.setAttribute("class","video-filters"); // restore}// set Ofelse{V.video.style.filter = "none";V.panel.classList.add("of");}});// On installe le themeV.panel.append( V.mkstyles() );// … et on ajoute la fonctionnalité de déplacementV.draggable(V.panel);V.initialized = true ;},// UI themetheme 	: `	/* Couleurs du theme en accord avec navigateur */:root{--vf-back-r: 255;--vf-back-v: 255;--vf-back-b: 255;--vf-back-c: rgb( var(--vf-back-r), var(--vf-back-v), var(--vf-back-b) );--vf-txt-c: black;--vf-active-c: #3e94f6; /* ff def value */}@media (prefers-color-scheme: dark){:root{--vf-back-r: 0;--vf-back-v: 0;--vf-back-b: 0;--vf-txt-c: white}}/* On positionne le bouton "FX" */button.video-fx{transform: translateY(-1.5em)}/* On optimise le panneau des filtres */.video-filters{position: absolute;z-index: 1000;width: clamp(30em,30vw,100%);background: rgba(var(--vf-back-r), var(--vf-back-v), var(--vf-back-b), .4 );backdrop-filter: blur(.3em) brightness(50%);border-radius: 1em;display: flex;justify-content: space-evenly;flex-wrap: wrap;top: 40vh;left: 10vw;font-weight: bold;margin-bottom: 1em;overflow: hidden;box-shadow: 0 0 .4em var(--vf-txt-c)}.video-filters.hidden{display:none}/* On ajoute la zone de drag */.video-filters header{text-align: center;padding: 1em;cursor: move;z-index: +1;background: var(--vf-back-c);color: var(--vf-txt-c);width:100%}/* On positionne les conteneurs pour chaque filtre */.video-filters > div{box-sizing: border-box;margin-bottom: 1em;max-width: 20em;transition:	all .5s ease-out}.video-filters.of > div{user-select: none;opacity: .4;filter: grayscale(100%) blur(1px);pointer-events:none;}/* On positionne les filtres */.video-filters label,.video-filters input{display: block;width: 100%}/* On règle les intitulés des filtres */.video-filters label{transform: translate(1em,0);color: white;text-transform: capitalize}/* Boutons, etc */.video-filters .close,input[type='checkbox'].switch{border-radius: 1em;width:1em;height: 1em;border: 2px solid var(--vf-txt-c)}/* On positionne le bouton de fermeture */.video-filters .close{display: block ;position: absolute ;top: .7em ;right: .7em;line-height: 0;color:transparent;font-size: 1.3em;}/* On crée le bouton switch pour les filtres */input[type='checkbox'].switch{display: inline-block;appearance:none;text-align: center;font-size: 2em;background: #777;transform: translate(0em,.2em) ;box-shadow: 0 0 0 var(--vf-txt-c), .3em 0 0 var(--vf-txt-c), .6em 0 0 var(--vf-txt-c);}input[type='checkbox'].switch:checked{transform: translate(1em,.2em) ;box-shadow: 0 0 0 var(--vf-txt-c), -.3em 0 0 var(--vf-txt-c), -.6em 0 0 var(--vf-txt-c);background: var(--vf-active-c)}`,// Constructeur pour la feuille de stylesmkstyles : function(){const s = D.createElement('style');s.type = 'text/css';s.id = 'video-fx-theme';s.innerHTML = V.theme;return s;// D.getElementsByTagName('head')[0].appendChild(s);},// Make element draggable// @see https://stackoverflow.com/questions/65022204/make-a-popup-modal-dialog-movable-draggable-once-it-has-appeareddraggable: function(el){varp1 = p2 = p3 = p4 = 0;// el.querySelector("header")V.header.onmousedown = startDrag;function startDrag(e){e = e || W.event;e.preventDefault();// Get the mouse cursor position at startupp3 = e.clientX;p4 = e.clientY;D.onmouseup = stopDrag;// Call a function whenever the cursor movesD.onmousemove = drag;}function drag(e){e = e || W.event;e.preventDefault();// Calculate the new cursor positionp1 = p3 - e.clientX;p2 = p4 - e.clientY;p3 = e.clientX;p4 = e.clientY;// Set the element's new position:el.style.top = (el.offsetTop - p2) + "px";el.style.left = (el.offsetLeft - p1) + "px";}function stopDrag(){// Stop moving when mouse button is releasedD.onmouseup = D.onmousemove = null;}}}})( window, document );// Appliquer// @see: https://addons.mozilla.org/fr/firefox/addon/greasemonkey/if(document.location.host==="www.youtube.com")videoFx.init();// @todo: extend to embed and other player