NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name Imagus Reddit Video Player // @namespace https://openuserjs.org/users/beypazarigurusu // @description Custom HTML5 player with shortcuts for Imagus-Reddit. // @version 0.0.1 // @author beypazarigurusu // @license MIT // @include *://*.reddit.com/* // @grant GM_xmlhttpRequest // @connect v.redd.it // @require https://cdn.jsdelivr.net/combine/npm/@violentmonkey/dom@1,npm/@violentmonkey/ui@0.4 // @require https://cdnjs.cloudflare.com/ajax/libs/arrive/2.4.1/arrive.min.js // @downloadURL https://openuserjs.org/install/beypazarigurusu/Imagus_Reddit_Video_Player.min.user.js // @updateURL https://openuserjs.org/meta/beypazarigurusu/Imagus_Reddit_Video_Player.meta.js // ==/UserScript== (function () { 'use strict'; var css_248z = ".imagus-video-wrapper{height:-moz-min-content!important;height:min-content!important;position:fixed!important;left:0!important;right:0!important;top:0!important;bottom:0!important;margin:auto!important;box-shadow:none!important;background-color:#000!important}.imagus-video-wrapper.stickied{box-shadow:0 0 0 100000px rgba(0,0,0,.7)!important}.imagus-video-wrapper videowrapper{height:0!important;padding-top:56.25%!important}.imagus-video-wrapper videowrapper video.custom-video-player{position:absolute!important}@media (min-width:177.778vh){.imagus-video-wrapper videowrapper{height:100%!important;padding-top:0!important}.imagus-video-wrapper videowrapper video.custom-video-player{position:relative!important}}html>div[style*=\"2147483647\"]>img[style*=\"display: block\"]~videowrapper{display:none!important}html>div[style*=\"2147483647\"]{background:none!important;box-shadow:none!important;border:0!important}html>div[style*=\"2147483647\"] videowrapper+div{-webkit-text-fill-color:#e6e6e6!important;box-shadow:none!important;width:100%!important;max-width:100%!important;box-sizing:border-box!important;overflow:hidden!important;text-overflow:ellipsis!important}html>div:not(.stickied) video.custom-video-player+controls,video[controls]:not(.custom-video-player){opacity:0!important;pointer-events:none!important}videowrapper{--wrapper-position:relative;position:var(--wrapper-position)!important;height:100%!important;display:block!important;font-size:0!important;top:0!important;bottom:0!important;left:0!important;right:0!important;background-color:#000!important;overflow:hidden!important}video.custom-video-player+controls timetooltip,video.custom-video-player+controls volumetooltip{position:absolute!important;display:none!important;top:-25px!important;height:22px!important;line-height:22px!important;text-align:center!important;border-radius:4px!important;font-size:12px!important;background:rgba(0,0,0,.7)!important;box-shadow:0 0 4px hsla(0,0%,100%,.5)!important;color:#fff!important;pointer-events:none!important}video.custom-video-player+controls timetooltip{margin-left:-25px!important;width:50px!important}video.custom-video-player+controls volumetooltip{margin-left:-20px!important;width:40px!important}video.custom-video-player.compact+controls timeline timetooltip{top:-25px!important}video.custom-video-player.compact+controls btn,video.custom-video-player.compact+controls rate,video.custom-video-player.compact+controls volume{height:24px!important;line-height:22px!important}video.custom-video-player.compact+controls volume input{padding-bottom:2px!important}video.custom-video-player.compact+controls btn:before{margin-top:-2px!important}video.custom-video-player.compact+controls volume>volumebar{top:6px!important}video.custom-video-player+controls timelinewrapper{line-height:20px!important}video.custom-video-player+controls timeline:hover timetooltip:not(.hidden),video.custom-video-player+controls volume:hover volumetooltip:not(.hidden){display:inline!important}video.custom-video-player{cursor:none!important;max-height:100%!important;height:100%!important;width:100%!important;margin:0!important;padding:0!important;top:0!important;bottom:0!important;left:0!important;right:0!important;background-color:#000!important;border-radius:0!important}video.custom-video-player:not(.contains-source):not([src*=\"/\"]){cursor:auto!important}video.custom-video-player:not(.contains-source):not([src*=\"/\"])+controls{display:none!important}video.custom-video-player+controls>*{background:none!important;outline:none!important;line-height:32px!important;font-family:monospace!important}video.custom-video-player.compact+controls>*{line-height:24px!important}video.custom-video-player+controls{--controls-z-index:1;white-space:nowrap!important;transition:opacity .5s ease 0s!important;background-color:rgba(0,0,0,.85)!important;height:32px!important;width:100%!important;cursor:default!important;font-size:18px!important;-moz-user-select:none!important;user-select:none!important;z-index:var(--controls-z-index)!important;flex:none!important;position:absolute!important;display:flex!important;flex-wrap:wrap!important;opacity:0!important;margin:0!important;bottom:0!important;left:0!important;right:0!important}video.custom-video-player.custom-video-player-hidden,video.custom-video-player.custom-video-player-hidden+controls{opacity:0!important;pointer-events:none!important}video.custom-video-player+controls:hover,video.custom-video-player.active+controls{opacity:1!important}video.custom-video-player+controls timeline{flex-grow:1!important;position:relative!important;align-items:center!important;flex-direction:column!important;height:100%!important}video.custom-video-player+controls timelinewrapper{flex:1 0 480px!important;position:relative!important;align-items:center!important}video.custom-video-player.compact+controls timelinewrapper{order:-1;flex-basis:100%!important;height:20px!important}video.custom-video-player.compact+controls timeline timebar{top:5px!important}video.custom-video-player.compact+controls currenttime,video.custom-video-player.compact+controls totaltime{line-height:20px!important}video.custom-video-player.compact+controls{height:44px!important}video.custom-video-player.compact-2+controls btn.begin,video.custom-video-player.compact-2+controls btn.skip-short,video.custom-video-player.compact-3+controls btn.rate-decrease,video.custom-video-player.compact-3+controls btn.rate-increase,video.custom-video-player.compact-3+controls rate,video.custom-video-player.compact-4+controls btn.skip-long{display:none!important}video.custom-video-player+controls>*{display:inline-flex!important}video.custom-video-player.compact-2+controls btn.rate-increase,video.custom-video-player.compact-4+controls btn.toggle-play{margin-right:auto!important}video.custom-video-player+controls timeline>timebar>timebuffer,video.custom-video-player+controls timeline>timebar>timeprogress,video.custom-video-player+controls volume>volumebar>volumetrail{position:absolute!important;flex:none!important;pointer-events:none!important;height:100%!important;border-radius:20px!important}video.custom-video-player+controls timeline>timebar,video.custom-video-player+controls volume>volumebar{position:absolute!important;height:10px!important;border-radius:20px!important;overflow:hidden!important;background-color:rgba(41,41,41,.85)!important;top:11px!important;left:0!important;right:0!important;pointer-events:none!important;z-index:-1!important;box-shadow:inset 0 0 0 1px #666,inset 0 0 5px hsla(0,0%,40%,.85)!important}video.custom-video-player+controls btn.disabled,video.custom-video-player+controls volume.disabled{filter:brightness(.4);pointer-events:none!important}video.custom-video-player.active.disabled,video.custom-video-player.disabled{cursor:default!important}video.custom-video-player.disabled+controls{opacity:1!important;filter:brightness(.3)sepia(1)hue-rotate(320deg)saturate(5)}video.custom-video-player.disabled+controls>*{pointer-events:none!important}video.custom-video-player+controls volume{max-width:70px!important;flex:1 0 48px!important;position:relative!important;margin:0 12px!important}video.custom-video-player+controls timeline>timebar>timebuffer{background-color:hsla(0,0%,100%,.2)!important;border-top-right-radius:20px!important;border-bottom-right-radius:20px!important;left:0!important}video.custom-video-player+controls timeline>timebar>timeprogress,video.custom-video-player+controls volume>volumebar>volumetrail{background-color:hsla(0,0%,100%,.4)!important;left:0!important}video.custom-video-player+controls volume.disabled volumetrail{width:0!important}video.custom-video-player+controls timeline>input{height:100%!important;width:100%!important}video.custom-video-player.active{cursor:pointer!important}video.custom-video-player+controls btn{border:none!important;cursor:pointer!important;background-color:initial!important;font-family:Segoe UI Symbol!important;font-size:0!important;margin:0!important;align-items:center!important;justify-content:center!important;height:32px!important;padding:0!important;flex:1 1 32px!important;max-width:46px!important;box-sizing:initial!important;position:relative!important;opacity:.86!important;text-shadow:none!important;transition:opacity .3s,text-shadow .3s!important;-webkit-text-fill-color:#fff!important}video.custom-video-player+controls btn.toggle-play{flex:1 1 46px!important}video.custom-video-player+controls btn:hover{opacity:1!important;text-shadow:0 0 8px #fff!important}video.custom-video-player.playback-rate-decreased+controls btn.rate-decrease,video.custom-video-player.playback-rate-increased+controls btn.rate-increase{-webkit-text-fill-color:#0ff!important}video.custom-video-player+controls rate{height:32px!important;width:42px!important;margin:0!important;display:unset!important;text-align:center!important;font-size:14px!important;flex-shrink:0!important;font-weight:700!important;letter-spacing:.5px!important;-webkit-text-fill-color:#fff!important;-moz-user-select:none!important;user-select:none!important;pointer-events:none!important;opacity:.86!important}video.custom-video-player+controls rate[data-current-rate]{pointer-events:all!important;cursor:pointer!important}video.custom-video-player+controls rate[data-current-rate]:hover{transition:opacity .3s,text-shadow .3s!important;opacity:1!important;text-shadow:0 0 8px #fff!important}video.custom-video-player+controls input[type=range]{-webkit-appearance:none!important;background-color:initial!important;outline:none!important;border:0!important;border-radius:6px!important;margin:0!important;top:0!important;bottom:0!important;left:0!important;right:0!important;padding:0!important;width:100%!important;position:relative!important}video.custom-video-player+controls input[type=range]::-webkit-slider-thumb{-webkit-appearance:none!important;background-color:#dbdbdb!important;border:0!important;height:14px!important;width:14px!important;border-radius:50%!important;pointer-events:none!important}video.custom-video-player.muted+controls volume input[type=range]::-webkit-slider-thumb{background-color:grey!important}video.custom-video-player+controls input[type=range]::-moz-range-thumb{-moz-appearance:none!important;background-color:#dbdbdb!important;border:0!important;height:14px!important;width:14px!important;border-radius:50%!important;pointer-events:none!important}video.custom-video-player.muted+controls volume input[type=range]::-moz-range-thumb{background-color:grey!important}video.custom-video-player+controls currenttime,video.custom-video-player+controls totaltime{font-family:monospace,arial!important;font-weight:700!important;font-size:14px!important;letter-spacing:.5px!important;height:100%!important;line-height:32px!important;min-width:58px!important;display:unset!important;-webkit-text-fill-color:#dbdbdb!important}video.custom-video-player+controls btn.rate-decrease,video.custom-video-player+controls btn.rate-increase{padding:0!important;flex:1 0 14px!important;max-width:24px!important}video.custom-video-player+controls btn.rate-decrease{margin-left:auto!important}video.custom-video-player+controls currenttime{padding:0 12px 0 0!important;margin-right:2px!important;text-align:right!important}video.custom-video-player+controls totaltime{padding:0 0 0 12px!important;margin-left:2px!important;text-align:left!important}.direct-video-top-level{margin:0!important;padding:0!important;display:flex!important;align-items:center!important;justify-content:center!important}.direct-video-top-level video{height:calc(56.25vw - 16.875px)!important;min-height:calc(56.25vw - 16.875px)!important;max-height:calc(56.25vw - 16.875px)!important;width:calc(100vw - 30px)!important;min-width:calc(100vw - 30px)!important;max-width:calc(100vw - 30px)!important;margin:auto!important}.direct-video-top-level>video.custom-video-player+controls{position:absolute!important;left:0!important;right:0!important;margin:0 auto!important;width:calc(100vw - 30px)!important;bottom:calc(50vh - 28.125vw + 8.4375px)!important}@media (min-width:177.778vh){.direct-video-top-level video{position:unset!important;height:calc(100vh - 30px)!important;min-height:calc(100vh - 30px)!important;max-height:calc(100vh - 30px)!important;margin:0 auto!important;padding:0!important;background-color:#000!important}.direct-video-top-level>video.custom-video-player+controls,.direct-video-top-level video{width:calc(177.77778vh - 53.33333px)!important;min-width:calc(177.77778vh - 53.33333px)!important;max-width:calc(177.77778vh - 53.33333px)!important}.direct-video-top-level>video.custom-video-player+controls{bottom:15px!important}}.native-fullscreen>:not(video):not(controls),video::-webkit-media-controls{display:none!important}.direct-video-top-level .native-fullscreen video.custom-video-player,.native-fullscreen video.custom-video-player{height:100vh!important;width:100vw!important;max-height:100vh!important;max-width:100vw!important;min-height:100vh!important;min-width:100vw!important;margin:0!important}.native-fullscreen video.custom-video-player+controls{position:fixed!important;bottom:0!important;left:0!important;right:0!important;margin:0!important;width:100vw!important;max-width:100vw!important}video.custom-video-player+controls btn:before{font-family:customVideoPlayerIconFont!important;font-weight:400!important;-webkit-font-smoothing:subpixel-antialiased!important;-moz-osx-font-smoothing:subpixel-antialiased!important;font-size:20px!important}video.custom-video-player+controls btn.skip-short.right:before{content:\"\\e90c\"!important}video.custom-video-player+controls btn.skip-short.left:before{content:\"\\e90b\"!important}video.custom-video-player+controls btn.skip-long.right:before{content:\"\\e901\"!important}video.custom-video-player+controls btn.skip-long.left:before{content:\"\\e902\"!important}video.custom-video-player+controls btn.begin:before{content:\"\\e908\"!important}video.custom-video-player+controls btn.toggle-play:before{content:\"\\e906\"!important;font-size:26px!important}video.custom-video-player.playing+controls btn.toggle-play:before{content:\"\\e905\"!important;font-size:24px!important}video.custom-video-player+controls btn.rate-decrease:before{content:\"\\ea0b\"!important;font-size:10px!important}video.custom-video-player+controls btn.rate-increase:before{content:\"\\ea0a\"!important;font-size:10px!important}video.custom-video-player+controls btn.mute:before{content:\"\\e90a\"!important;font-size:22px!important}video.custom-video-player.muted+controls btn.mute:before{content:\"\\e909\"!important;font-size:22px!important}video.custom-video-player+controls btn.mute.disabled:before{content:\"\\e909\"!important}video.custom-video-player+controls btn.expand:before{content:\"\\e904\"!important;font-size:24px!important}.native-fullscreen video.custom-video-player+controls btn.expand:before{content:\"\\e903\"!important;font-size:24px!important}@font-face{font-family:customVideoPlayerIconFont;src:url(data:application/x-font-woff;charset=utf-8;base64,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) format(\"woff\"),url(customVideoPlayerIconFont.ttf) format(\"truetype\"),url(customVideoPlayerIconFont.svg#customVideoPlayerIconFont) format(\"svg\");font-weight:400;font-style:normal}"; /* global GM_xmlhttpRequest */ document.head.append(VM.createElement("style", { id: "custom-video-player-style", className: "stylus" }, css_248z)); let imagusAudio; let audioSync; let audioError; const $ = document.querySelector.bind(document); // const $$ = document.querySelectorAll.bind(document); const SETTINGS = { // delay to hide contols and cursor if inactive (set to 3000 milliseconds) hideControls: 300, // delay for fullscreen double-click (set to 300 milliseconds) clickDelay: 300, // right-click delay to match imagus user setting (set to 0 milliseconds) imagusStickyDelay: 0, // right/left arrows keys or inner skip buttons (set to 10 seconds) skipNormal: 10, // Shift + Arrow keys or outer skip buttons (set to 30 seconds) skipShift: 30, // Ctrl + Arrow keys skip (set to 1 minute) skipCtrl: 1 }; const SHORTCUT_FUNCTIONS = { toggleCaptions: v => { const validTracks = []; for (let i = 0; i < v.textTracks.length; i += 1) { const tt = v.textTracks[i]; if (tt.mode === 'showing') { tt.mode = 'disabled'; if (v.textTracks.addEventListener) { // If text track event listeners are supported // (they are on the most recent Chrome), add // a marker to remember the old track. Use a // listener to delete it if a different track // is selected. v.cbhtml5vsLastCaptionTrack = tt.label; const cleanup = e => { for (let j = 0; j < v.textTracks.length; j += 1) { const ott = v.textTracks[j]; if (ott.mode === 'showing') { delete v.cbhtml5vsLastCaptionTrack; v.textTracks.removeEventListener('change', cleanup); return; } } }; v.textTracks.addEventListener('change', cleanup); } return; } if (tt.mode !== 'hidden') { validTracks.push(tt); } } // If we got here, none of the tracks were selected. if (validTracks.length === 0) { return true; // Do not prevent default if no UI activated } // Find the best one and select it. validTracks.sort((a, b) => { if (v.cbhtml5vsLastCaptionTrack) { const lastLabel = v.cbhtml5vsLastCaptionTrack; if (a.label === lastLabel && b.label !== lastLabel) { return -1; } if (b.label === lastLabel && a.label !== lastLabel) { return 1; } } const aLang = a.language.toLowerCase(); const bLang = b.language.toLowerCase(); const navLang = navigator.language.toLowerCase(); if (aLang === navLang && bLang !== navLang) { return -1; } if (bLang === navLang && aLang !== navLang) { return 1; } const aPre = aLang.split('-')[0]; const bPre = bLang.split('-')[0]; const navPre = navLang.split('-')[0]; if (aPre === navPre && bPre !== navPre) { return -1; } if (bPre === navPre && aPre !== navPre) { return 1; } return 0; })[0].mode = 'showing'; }, togglePlay: v => { if (v.paused) { v.play(); } else { v.pause(); } }, toStart: v => { v.currentTime = 0; }, toEnd: v => { v.currentTime = v.duration; }, skipLeft: (v, key, shift, ctrl) => { if (shift) { v.currentTime -= SETTINGS.skipShift; } else if (ctrl) { v.currentTime -= SETTINGS.skipCtrl; } else { v.currentTime -= SETTINGS.skipNormal; } }, skipRight: (v, key, shift, ctrl) => { if (shift) { v.currentTime += SETTINGS.skipShift; } else if (ctrl) { v.currentTime += SETTINGS.skipCtrl; } else { v.currentTime += SETTINGS.skipNormal; } }, increaseVol: v => { if (audioError) return; if (v.nextSibling.querySelector('volume.disabled')) { v.volume = 0; return; } const increase = (v.volume + 0.1).toFixed(1); if (v.muted) { v.muted = !v.muted; v.volume = 0.1; } else { if (v.volume <= 0.9) { v.volume = increase; } else { v.volume = 1; } } }, decreaseVol: v => { if (audioError) return; if (v.nextSibling.querySelector('volume.disabled')) { v.volume = 0; return; } const decrease = (v.volume - 0.1).toFixed(1); if (v.volume >= 0.1) { v.volume = decrease; } else { v.volume = 0; } }, toggleMute: v => { v.muted = !v.muted; if (audioSync) imagusAudio.muted = v.muted; }, toggleFS: v => { if (document.fullscreenElement) { document.exitFullscreen(); v.parentElement.classList.remove('native-fullscreen'); } else { v.parentElement.classList.add('native-fullscreen'); v.parentElement.requestFullscreen(Element.ALLOW_KEYBOARD_INPUT); } }, reloadVideo: v => { const currTime = v.currentTime; v.load(); v.currentTime = currTime; }, slowOrPrevFrame: (v, key, shift) => { if (shift) { // Less-Than v.currentTime -= 1 / 60; } else { // Comma if (v.playbackRate >= 0.1) { const decrease = (v.playbackRate - 0.1).toFixed(2); const rate = v.nextSibling.querySelector('rate'); v.playbackRate = decrease; rate.textContent = `${v.playbackRate}x`; if (v.playbackRate !== 1) { rate.setAttribute('data-current-rate', `${v.playbackRate}x`); } if (v.playbackRate === 0.9) { v.classList.add('playback-rate-decreased'); } else if (v.playbackRate === 1.1) { v.classList.add('playback-rate-increased'); } else if (v.playbackRate === 1) { v.classList.remove('playback-rate-decreased'); v.classList.remove('playback-rate-increased'); rate.removeAttribute('data-current-rate'); } } else { v.playbackRate = 0; } if (audioSync) imagusAudio.playbackRate = v.playbackRate; } }, fastOrNextFrame: (v, key, shift) => { if (shift) { // Greater-Than v.currentTime += 1 / 60; } else { // Period if (v.playbackRate <= 15.9) { const increase = (v.playbackRate += 0.1).toFixed(2); const rate = v.nextSibling.querySelector('rate'); v.playbackRate = increase; rate.textContent = `${v.playbackRate}x`; if (v.playbackRate !== 1) { rate.setAttribute('data-current-rate', `${v.playbackRate}x`); } if (v.playbackRate === 0.9) { v.classList.add('playback-rate-decreased'); } else if (v.playbackRate === 1.1) { v.classList.add('playback-rate-increased'); } else if (v.playbackRate === 1) { v.classList.remove('playback-rate-decreased'); v.classList.remove('playback-rate-increased'); rate.removeAttribute('data-current-rate'); } } else { v.playbackRate = 16; } if (audioSync) imagusAudio.playbackRate = v.playbackRate; } }, normalSpeed: v => { // ? v.playbackRate = v.defaultPlaybackRate; if (audioSync) imagusAudio.playbackRate = v.playbackRate; v.classList.remove('playback-rate-decreased'); v.classList.remove('playback-rate-increased'); v.nextSibling.querySelector('rate').textContent = '1x'; v.nextSibling.querySelector('rate').removeAttribute('data-current-rate'); }, toPercentage: (v, key) => { v.currentTime = v.duration * (key - 48) / 10.0; } }; const KEY_FUNCTIONS = { 32: SHORTCUT_FUNCTIONS.togglePlay, // Space 75: SHORTCUT_FUNCTIONS.togglePlay, // K 35: SHORTCUT_FUNCTIONS.toEnd, // End 48: SHORTCUT_FUNCTIONS.toStart, // 0 36: SHORTCUT_FUNCTIONS.toStart, // Home 37: SHORTCUT_FUNCTIONS.skipLeft, // Left arrow 74: SHORTCUT_FUNCTIONS.skipLeft, // J 39: SHORTCUT_FUNCTIONS.skipRight, // Right arrow 76: SHORTCUT_FUNCTIONS.skipRight, // L 38: SHORTCUT_FUNCTIONS.increaseVol, // Up arrow 40: SHORTCUT_FUNCTIONS.decreaseVol, // Down arrow 77: SHORTCUT_FUNCTIONS.toggleMute, // M 70: SHORTCUT_FUNCTIONS.toggleFS, // F 67: SHORTCUT_FUNCTIONS.toggleCaptions, // C 82: SHORTCUT_FUNCTIONS.reloadVideo, // R 188: SHORTCUT_FUNCTIONS.slowOrPrevFrame, // Comma or Less-Than 190: SHORTCUT_FUNCTIONS.fastOrNextFrame, // Period or Greater-Than 191: SHORTCUT_FUNCTIONS.normalSpeed, // Forward slash or ? 49: SHORTCUT_FUNCTIONS.toPercentage, // 1 50: SHORTCUT_FUNCTIONS.toPercentage, // 2 51: SHORTCUT_FUNCTIONS.toPercentage, // 3 52: SHORTCUT_FUNCTIONS.toPercentage, // 4 53: SHORTCUT_FUNCTIONS.toPercentage, // 5 54: SHORTCUT_FUNCTIONS.toPercentage, // 6 55: SHORTCUT_FUNCTIONS.toPercentage, // 7 56: SHORTCUT_FUNCTIONS.toPercentage, // 8 57: SHORTCUT_FUNCTIONS.toPercentage // 9 }; function customPlayer(v) { let videoWrapper; let savedTimeKey; let mouseDown; let isPlaying; let isSeeking; let earlyXposPercent; let preventMouseMove; let controlsTimeout; let imagusMouseTimeout; let imagusVid; let muteTillSync; let loaded; let error; let elToFocus; let clickCount = 0; let repeat = 0; const directVideo = /video/.test(document.contentType) && document.body.firstElementChild === v; const controls = document.createElement('controls'); const imagus = v.classList.contains('imagus'); if (imagus && !imagusVid) { imagusVid = v; imagusAudio = document.createElement('video'); imagusAudio.preload = 'auto'; imagusAudio.autoplay = 'true'; imagusAudio.className = 'imagus imagus-audio'; imagusAudio.style = 'display: none!important;'; imagusVid.parentElement.insertBefore(imagusAudio, imagusVid); } if (directVideo) { elToFocus = document.body; if (self === top) { document.body.classList.add('direct-video-top-level'); } else { document.body.classList.add('direct-video-embed'); } } else { elToFocus = v; videoWrapper = document.createElement('videowrapper'); v.parentNode.insertBefore(videoWrapper, v); videoWrapper.appendChild(v); if (!imagus) { const compStyles = getComputedStyle(v); const position = compStyles.getPropertyValue('position'); const zIndex = compStyles.getPropertyValue('z-index'); if (position === 'absolute') { videoWrapper.style.setProperty('--wrapper-position', `${position}`); } if (zIndex !== 'auto') { controls.style.setProperty('--controls-z-index', `calc(${zIndex} + 1)`); } } } v.parentNode.insertBefore(controls, v.nextSibling); const playButton = document.createElement('btn'); playButton.className = 'toggle-play'; controls.appendChild(playButton); const beginButton = document.createElement('btn'); beginButton.className = 'begin'; controls.appendChild(beginButton); const skipLongLeft = document.createElement('btn'); skipLongLeft.className = 'skip-long left'; controls.appendChild(skipLongLeft); const skipShortLeft = document.createElement('btn'); skipShortLeft.className = 'skip-short left'; controls.appendChild(skipShortLeft); const skipShortRight = document.createElement('btn'); skipShortRight.className = 'skip-short right'; controls.appendChild(skipShortRight); const skipLongRight = document.createElement('btn'); skipLongRight.className = 'skip-long right'; controls.appendChild(skipLongRight); const timelineWrapper = document.createElement('timelinewrapper'); controls.appendChild(timelineWrapper); const currentTime = document.createElement('currenttime'); currentTime.textContent = '0:00'; timelineWrapper.appendChild(currentTime); const timeline = document.createElement('timeline'); timelineWrapper.appendChild(timeline); const timeBar = document.createElement('timebar'); timeline.appendChild(timeBar); const timeBuffer = document.createElement('timebuffer'); timeBar.appendChild(timeBuffer); const timeProgress = document.createElement('timeprogress'); timeBar.appendChild(timeProgress); const timeSlider = document.createElement('input'); timeSlider.type = 'range'; timeSlider.value = 0; timeSlider.min = 0; timeSlider.max = 100; timeSlider.step = 0.01; timeSlider.textContent = ''; timeline.appendChild(timeSlider); const timeTooltip = document.createElement('timetooltip'); timeTooltip.className = 'hidden'; timeTooltip.textContent = '-:-'; timeline.appendChild(timeTooltip); const totalTime = document.createElement('totaltime'); totalTime.textContent = '-:-'; timelineWrapper.appendChild(totalTime); const rateDecrease = document.createElement('btn'); rateDecrease.className = 'rate-decrease'; controls.appendChild(rateDecrease); const rate = document.createElement('rate'); rate.textContent = '1x'; controls.appendChild(rate); const rateIncrease = document.createElement('btn'); rateIncrease.className = 'rate-increase'; controls.appendChild(rateIncrease); const volume = document.createElement('volume'); controls.appendChild(volume); const volumeBar = document.createElement('volumebar'); volume.appendChild(volumeBar); const volumeTrail = document.createElement('volumetrail'); volumeBar.appendChild(volumeTrail); const volumeSlider = document.createElement('input'); volumeSlider.type = 'range'; volumeSlider.min = 0; volumeSlider.max = 1; volumeSlider.step = 0.01; volumeSlider.textContent = ''; volume.appendChild(volumeSlider); const volumeTooltip = document.createElement('volumetooltip'); volumeTooltip.className = 'hidden'; volumeTooltip.textContent = '0%'; volume.appendChild(volumeTooltip); const muteButton = document.createElement('btn'); muteButton.className = 'mute'; controls.appendChild(muteButton); const expandButton = document.createElement('btn'); expandButton.className = 'expand'; controls.appendChild(expandButton); v.classList.remove('custom-video-player-hidden'); if (v.querySelector('source')) v.classList.add('contains-source'); if (videoWrapper) enforcePosition(); volumeValues(); v.onloadedmetadata = ev => { loaded = true; SHORTCUT_FUNCTIONS.normalSpeed(v); savedTimeKey = `${location.pathname}${location.search}${v.duration}`; const savedTime = localStorage.getItem(savedTimeKey); if (timeSlider.value === '0') { if (savedTime) v.currentTime = savedTime; } else if (earlyXposPercent) { const time = earlyXposPercent * v.duration / 100; v.currentTime = time; } currentTime.textContent = formatTime(v.currentTime); totalTime.textContent = formatTime(v.duration); v.classList.remove('disabled'); sliderValues(ev); }; v.onloadeddata = () => { const imagusVreddit = /v(cf)?\.redd\.it/.test(v.src); const vHasAudio = hasAudio(); if (!vHasAudio && !imagusVreddit) { v.classList.add('muted'); volumeSlider.value = 0; muteButton.classList.add('disabled'); volume.classList.add('disabled'); } else if (vHasAudio && !imagusVreddit) { if (v.volume && !v.muted) v.classList.remove('muted'); volumeValues(); if (volume.classList.contains('disabled')) { muteButton.classList.remove('disabled'); volume.classList.remove('disabled'); } } elToFocus.focus({ preventScroll: true }); if (v.duration <= SETTINGS.skipNormal) { skipShortLeft.classList.add('disabled'); skipShortRight.classList.add('disabled'); } else { skipShortLeft.classList.remove('disabled'); skipShortRight.classList.remove('disabled'); } if (v.duration <= SETTINGS.skipShift) { skipLongLeft.classList.add('disabled'); skipLongRight.classList.add('disabled'); } else { skipLongLeft.classList.remove('disabled'); skipLongRight.classList.remove('disabled'); } if (v.paused) { v.classList.add('paused'); if (videoWrapper) videoWrapper.classList.add('paused'); } if (imagus) v.currentTime = 0; }; v.oncanplay = () => { v.oncanplay = null; if (!loaded) { v.load(); // console.log('Custom video player reloaded'); } }; v.onprogress = () => { if (v.readyState > 1 && v.duration > 0) { const buffer = v.buffered.end(v.buffered.length - 1) / v.duration * 100; timeBuffer.style.width = `${buffer}%`; } }; v.ontimeupdate = ev => { if (v.readyState > 0) { if (v.duration > 0 && !mouseDown) { sliderValues(ev); totalTime.textContent = formatTime(v.duration); if (!imagus && savedTimeKey) localStorage.setItem(savedTimeKey, v.currentTime); } } }; v.onvolumechange = ev => { if (audioError) return; if (audioSync) imagusAudio.volume = v.volume; if (v.muted || !v.volume) { v.classList.add('muted'); volumeSlider.value = 0; volumeTrail.style.width = '0'; localStorage.setItem('videomuted', 'true'); } else { v.classList.remove('muted'); sliderValues(ev); if (v.volume > 0.1) { localStorage.setItem('videovolume', v.volume); } else { localStorage.setItem('videovolume', 0.1); } localStorage.setItem('videomuted', 'false'); } }; v.onplay = () => { if (v === imagusVid && audioSync) imagusAudio.play(); v.classList.remove('paused'); if (videoWrapper) videoWrapper.classList.remove('paused'); v.classList.add('playing'); }; v.onpause = () => { if (v === imagusVid && audioSync) imagusAudio.pause(); if (!isSeeking) { v.classList.remove('playing'); v.classList.add('paused'); if (videoWrapper) videoWrapper.classList.add('paused'); } }; v.onended = () => { if (localStorage.getItem(savedTimeKey)) localStorage.removeItem(savedTimeKey); savedTimeKey = false; }; v.onemptied = () => { if (v === imagusVid) { if (v.src !== '') { if (/v(cf)?\.redd\.it/.test(v.src)) { const prefix = v.src.split('DASH')[0].replace('vcf.', 'v.'); const audioSrc = `${prefix}DASH_audio.mp4`; GM_xmlhttpRequest({ method: 'GET', url: audioSrc, onload: xhr => { imagusAudio.src = xhr.status >= 200 && xhr.status < 300 ? audioSrc : `${prefix}audio`; }, onerror: () => { imagusAudio.src = `${prefix}audio`; } }); if (!imagusAudio.muted) { muteTillSync = true; imagusAudio.muted = true; } if (imagusVid.hasAttribute('loop')) imagusAudio.setAttribute('loop', 'true'); } v.parentElement.parentElement.classList.add('imagus-video-wrapper'); window.addEventListener('click', imagusClick, true); document.addEventListener('keyup', imagusKeys, true); document.addEventListener('mousedown', imagusMouseDown, true); document.addEventListener('mouseup', imagusMouseUp, true); } else { audioSync = false; audioError = false; imagusAudio.pause(); imagusAudio.removeAttribute('src'); imagusAudio.load(); imagusAudio.removeAttribute('loop'); v.parentElement.parentElement.removeAttribute('class'); timeTooltip.classList.add('hidden'); window.removeEventListener('click', imagusClick, true); document.removeEventListener('keyup', imagusKeys, true); document.removeEventListener('mousedown', imagusMouseDown, true); document.removeEventListener('mouseup', imagusMouseUp, true); } } }; v.onerror = () => { error = true; elToFocus.blur(); v.classList.add('disabled'); }; v.onmousedown = e => { if (error && e.button !== 2) return; e.stopPropagation(); e.stopImmediatePropagation(); if (e.button === 0) { clickCount += 1; const checkState = v.paused; if (clickCount === 1) { setTimeout(() => { if (clickCount === 1) { // avoid conflicts with existing click listeners const recheckState = v.paused; if (checkState === recheckState) SHORTCUT_FUNCTIONS.togglePlay(v); } else { SHORTCUT_FUNCTIONS.toggleFS(v); } clickCount = 0; }, SETTINGS.clickDelay); } } else if (e.button === 2) { window.addEventListener('contextmenu', preventHijack, true); } }; v.onmouseup = e => { if (e.button === 2) { setTimeout(() => { window.removeEventListener('contextmenu', preventHijack, true); }, 100); } if (error) elToFocus.blur(); }; v.onmousemove = () => { if (controlsTimeout) { clearTimeout(controlsTimeout); } else { v.classList.add('active'); } if (videoWrapper) { videoWrapper.classList.add('active'); } controlsTimeout = setTimeout(() => { controlsTimeout = false; v.classList.remove('active'); if (videoWrapper) { videoWrapper.classList.remove('active'); } }, SETTINGS.hideControls); }; new ResizeObserver(() => { compactControls(); }).observe(v); controls.onmouseup = () => { if (error) return; elToFocus.focus({ preventScroll: true }); }; timeSlider.onmousemove = ev => sliderValues(ev); timeSlider.oninput = ev => sliderValues(ev); timeSlider.onmousedown = e => { if (e.button > 0) return; mouseDown = true; isSeeking = true; if (timeTooltip.classList.contains('hidden')) sliderValues(e); if (v.readyState > 0) { if (!v.paused) { isPlaying = true; v.pause(); } else { isPlaying = false; } } }; timeSlider.onmouseup = e => { if (e.button > 0) return; mouseDown = false; isSeeking = false; if (v.readyState > 0) { sliderValues(e); if (isPlaying) { v.play(); isPlaying = false; } } }; volumeSlider.onmousemove = ev => sliderValues(ev); volumeSlider.oninput = ev => { if (v.muted) SHORTCUT_FUNCTIONS.toggleMute(v); sliderValues(ev); }; muteButton.onmouseup = e => { if (e.button > 0) return; const lastVolume = localStorage.getItem('videovolume'); if (v.muted || v.volume) SHORTCUT_FUNCTIONS.toggleMute(v); v.volume = lastVolume; if (audioSync) imagusAudio.muted = v.muted; }; playButton.onmouseup = e => { if (e.button > 0) return; SHORTCUT_FUNCTIONS.togglePlay(v); }; skipShortLeft.onmouseup = e => { if (e.button > 0) return; SHORTCUT_FUNCTIONS.skipLeft(v); }; skipShortRight.onmouseup = e => { if (e.button > 0) return; SHORTCUT_FUNCTIONS.skipRight(v); }; skipLongLeft.onmouseup = e => { if (e.button > 0) return; v.currentTime -= SETTINGS.skipShift; }; skipLongRight.onmouseup = e => { if (e.button > 0) return; v.currentTime += SETTINGS.skipShift; }; beginButton.onmouseup = e => { if (e.button > 0) return; v.currentTime = 0; timeSlider.value = 0; timeProgress.style.width = '0'; currentTime.textContent = '0:00'; }; rateDecrease.onmouseup = e => { if (e.button > 0) return; SHORTCUT_FUNCTIONS.slowOrPrevFrame(v); }; rateIncrease.onmouseup = e => { if (e.button > 0) return; SHORTCUT_FUNCTIONS.fastOrNextFrame(v); }; rate.onmouseup = e => { if (e.button > 0) return; SHORTCUT_FUNCTIONS.normalSpeed(v); }; rate.onmouseenter = () => { rate.textContent = '1x?'; }; rate.onmouseleave = () => { const currentRate = rate.getAttribute('data-current-rate'); if (currentRate) rate.textContent = currentRate; }; expandButton.onmouseup = e => { if (e.button > 0) return; SHORTCUT_FUNCTIONS.toggleFS(v); }; // exiting fullscreen by escape key or other browser provided method document.onfullscreenchange = () => { if (!document.fullscreenElement) { const nativeFS = $('.native-fullscreen'); if (nativeFS) nativeFS.classList.remove('native-fullscreen'); } }; if (imagusVid) { imagusAudio.onloadedmetadata = () => { audioSync = true; if (v.hasAttribute('autoplay')) imagusAudio.play(); }; imagusAudio.onloadeddata = () => { if (v.volume && !v.muted) v.classList.remove('muted'); volumeValues(); if (volume.classList.contains('disabled')) { muteButton.classList.remove('disabled'); volume.classList.remove('disabled'); } }; imagusAudio.onended = () => { imagusAudio.currentTime = 0; if (imagusVid.hasAttribute('loop')) imagusAudio.play(); }; imagusAudio.onerror = () => { audioError = true; v.classList.add('muted'); volumeSlider.value = 0; muteButton.classList.add('disabled'); volume.classList.add('disabled'); }; } if (directVideo) { v.removeAttribute('tabindex'); document.body.setAttribute('tabindex', '0'); document.addEventListener('keydown', docHandleKeyDown, true); document.addEventListener('keypress', docHandleKeyOther, true); document.addEventListener('keyup', docHandleKeyOther, true); } else { v.addEventListener('keydown', handleKeyDown, false); v.addEventListener('keypress', handleKeyOther, false); v.addEventListener('keyup', handleKeyOther, false); } function sliderValues(ev) { let slider; let xPosition; const vid = audioSync ? imagusAudio && v : v; const eType = ev ? ev.type : event && event.type; const eTime = eType === 'timeupdate'; const eVolume = eType === 'volumechange'; const eMeta = eType === 'loadedmetadata'; const eData = eType === 'loadeddata'; const eInput = eType === 'input'; const eMouseUp = eType === 'mouseup'; const eMouseMove = eType === 'mousemove'; const eMouseDown = eType === 'mousedown'; if (eMeta || eTime || eVolume || eData || !ev) { slider = eMeta || eTime ? timeSlider : volumeSlider; } else { slider = ev.target; } const tooltip = slider.nextSibling; const timeTarget = slider === timeSlider; const sliderWidth = slider.clientWidth; const halfSlider = sliderWidth / 2; const slider14ths = halfSlider / 7; const eX = ev && ev.offsetX; const start7 = eX <= 7; const end7 = eX >= sliderWidth - 7; if (eMouseMove || eMouseDown) { if (start7 || end7) { xPosition = start7 ? 0 : sliderWidth; } else { xPosition = eX < halfSlider ? (eX + (-7 + eX / slider14ths)).toFixed(1) : (eX + (eX - halfSlider) / slider14ths).toFixed(1); } } if (eMeta || eTime || eVolume || eData || !ev) { xPosition = eMeta || eTime ? (100 / v.duration * v.currentTime * sliderWidth / 100).toFixed(1) : (v.volume * sliderWidth).toFixed(1); } if (eTime && ev.target === imagusVid && audioSync) { if (imagusVid.currentTime - imagusAudio.currentTime >= 0.1 || imagusVid.currentTime - imagusAudio.currentTime <= -0.1) { imagusAudio.currentTime = imagusVid.currentTime + 0.06; // console.debug('time sync corrected'); if (muteTillSync && imagusAudio.readyState > 2) { imagusAudio.muted = false; muteTillSync = false; // console.debug('unmuted after time correct'); } } else if (muteTillSync && imagusAudio.readyState > 2) { imagusAudio.muted = false; muteTillSync = false; // console.debug('unmuted'); } } if (eInput || eMouseUp) xPosition = +tooltip.getAttribute('data-x-position'); const xPosPercent = timeTarget ? xPosition / sliderWidth * 100 : Math.round(xPosition / sliderWidth * 100); let time = xPosPercent * v.duration / 100; if (eInput || eMeta || eTime || eVolume || eData || !ev) { const valueTrail = timeTarget ? timeProgress : volumeTrail; const offset = halfSlider < xPosition ? -7 + xPosition / slider14ths : (xPosition - halfSlider) / slider14ths; slider.value = timeTarget ? xPosPercent : xPosPercent / 100; valueTrail.style.width = `calc(${xPosPercent}% - ${offset}px)`; if (eInput && !timeTarget) { if (start7 || end7) { vid.volume = start7 ? 0 : 1; } else { vid.volume = xPosPercent / 100; } } if (eInput && timeTarget && v.readyState > 0) currentTime.textContent = formatTime(time); if (eTime) currentTime.textContent = formatTime(v.currentTime); if (eInput && timeTarget && v.readyState < 1) earlyXposPercent = xPosPercent; if (eMeta && !tooltip.classList.contains('hidden')) { xPosition = +tooltip.getAttribute('data-x-position'); time = xPosition / sliderWidth * v.duration; tooltip.textContent = formatTime(time); } } else if (eMouseUp) { if (audioSync) { if (start7 || end7) { imagusAudio.currentTime = start7 ? 0 : v.duration; } else { imagusAudio.currentTime = time; } } if (start7 || end7) { v.currentTime = start7 ? 0 : v.duration; } else { v.currentTime = time; } preventMouseMove = true; setTimeout(() => { preventMouseMove = false; }, 10); } else if (eMouseMove || eMouseDown) { if (!preventMouseMove || eMouseDown) { tooltip.dataset.xPosition = xPosition; tooltip.style.left = `${eX}px`; if (v.readyState > 0 && timeTarget) tooltip.textContent = formatTime(time); if (!timeTarget) tooltip.textContent = `${xPosPercent}%`; } tooltip.classList.remove('hidden'); preventMouseMove = false; } } function formatTime(t) { let seconds = Math.round(t); const minutes = Math.floor(seconds / 60); if (minutes > 0) seconds -= minutes * 60; if (seconds.toString().length === 1) seconds = `0${seconds}`; return `${minutes}:${seconds}`; } function volumeValues() { const videovolume = localStorage.getItem('videovolume'); const videomuted = localStorage.getItem('videomuted'); if (!videovolume && !videomuted || videovolume && videovolume === '1' && videomuted && videomuted !== 'true') { v.volume = 1; volumeSlider.value = 1; volumeTrail.style.width = '100%'; localStorage.setItem('videovolume', v.volume); localStorage.setItem('videomuted', 'false'); } else if (videomuted && videomuted === 'true') { v.classList.add('muted'); volumeSlider.value = 0; volumeTrail.style.width = '0'; v.muted = true; } else { v.volume = videovolume; if (audioSync) imagusAudio.volume = v.volume; sliderValues(); if (!volumeSlider.clientWidth) { new MutationObserver((_, observer) => { const volumeWidthSet = v.parentElement.querySelector('volume input').clientWidth; if (volumeWidthSet) { sliderValues(); observer.disconnect(); } }).observe(v.parentElement, { childList: true, subtree: true, attributes: true }); } } } function hasAudio() { return v.mozHasAudio || Boolean(v.webkitAudioDecodedByteCount) || Boolean(v.audioTracks && v.audioTracks.length); } function compactControls() { const width = v.clientWidth; if (width && width < 892) { v.classList.add('compact'); } else { v.classList.remove('compact'); } if (width && width < 412) { v.classList.add('compact-2'); } else { v.classList.remove('compact-2'); } if (width && width < 316) { v.classList.add('compact-3'); } else { v.classList.remove('compact-3'); } if (width && width < 246) { v.classList.add('compact-4'); } else { v.classList.remove('compact-4'); } } function imagusMouseDown(e) { const vid = $('.imagus-video-wrapper'); if (vid && e.button === 2) { e.stopImmediatePropagation(); imagusMouseTimeout = setTimeout(() => { imagusMouseTimeout = 'sticky'; }, SETTINGS.imagusStickyDelay); } } function imagusMouseUp(e) { const vid = $('.imagus-video-wrapper'); if (vid && e.button === 2) { if (imagusMouseTimeout === 'sticky') { vid.classList.add('stickied'); setTimeout(() => { v.removeAttribute('controls'); }); if (volume.classList.contains('disabled')) volumeSlider.value = 0; document.removeEventListener('mousedown', imagusMouseDown, true); document.removeEventListener('mouseup', imagusMouseUp, true); } else { clearInterval(imagusMouseTimeout); imagusMouseTimeout = false; } } } function imagusClick(e) { const imagusStickied = $('.imagus-video-wrapper.stickied'); if (imagusStickied) { if (e.target.closest('.imagus-video-wrapper.stickied')) { e.stopImmediatePropagation(); } else { imagusStickied.removeAttribute('class'); e.preventDefault(); } } } function imagusKeys(e) { const vid = $('.imagus-video-wrapper'); if (vid) { if (e.keyCode === 13 || e.keyCode === 90) { vid.classList.add('stickied'); setTimeout(() => { v.removeAttribute('controls'); }); if (volume.classList.contains('disabled')) volumeSlider.value = 0; document.removeEventListener('keyup', imagusKeys, true); document.removeEventListener('mousedown', imagusMouseDown, true); document.removeEventListener('mouseup', imagusMouseUp, true); } } } function handleKeyDown(e) { if (e.altKey || e.metaKey) return true; // Do not activate const func = KEY_FUNCTIONS[e.keyCode]; if (func) { if (func.length < 3 && e.shiftKey || func.length < 4 && e.ctrlKey) return true; // Do not activate func(e.target, e.keyCode, e.shiftKey, e.ctrlKey); e.preventDefault(); e.stopPropagation(); e.stopImmediatePropagation(); return false; } } function handleKeyOther(e) { if (e.altKey || e.metaKey) return true; // Do not prevent default const func = KEY_FUNCTIONS[e.keyCode]; if (func) { if (func.length < 3 && e.shiftKey || func.length < 4 && e.ctrlKey) return true; // Do not prevent default e.preventDefault(); e.stopPropagation(); e.stopImmediatePropagation(); return false; } } function docHandleKeyDown(e) { if (document.body !== document.activeElement || e.altKey || e.metaKey) return true; // Do not activate const func = KEY_FUNCTIONS[e.keyCode]; if (func) { if (func.length < 3 && e.shiftKey || func.length < 4 && e.ctrlKey) return true; // Do not activate func(v, e.keyCode, e.shiftKey, e.ctrlKey); e.preventDefault(); e.stopPropagation(); return false; } } function docHandleKeyOther(e) { if (document.body !== document.activeElement || e.altKey || e.metaKey) return true; // Do not prevent default const func = KEY_FUNCTIONS[e.keyCode]; if (func) { if (func.length < 3 && e.shiftKey || func.length < 4 && e.ctrlKey) return true; // Do not prevent default e.preventDefault(); e.stopPropagation(); return false; } } // circumvent any scripts attempting to hijack video context menus function preventHijack(e) { e.stopPropagation(); e.stopImmediatePropagation(); const redirectEvent = e.target.ownerDocument.createEvent('MouseEvents'); redirectEvent.initMouseEvent(e, e.bubbles, e.cancelable); return e; } function enforcePosition() { setTimeout(() => { let controlsDisplaced = controls !== v.nextSibling; const vidDisplaced = videoWrapper !== v.parentNode; if (vidDisplaced || controlsDisplaced) { if (vidDisplaced) videoWrapper.appendChild(v); controlsDisplaced = v !== controls.previousSibling; if (controlsDisplaced) videoWrapper.insertBefore(controls, v.nextSibling); const bs = videoWrapper.querySelectorAll('videowrapper > *:not(video):not(controls)'); for (let i = 0; i < bs.length; i += 1) { bs[i].remove(); } } repeat += 1; if (repeat < 10) enforcePosition.call(this); }, 100); } } document.arrive('video[controls], video[style*="visibility: inherit !important"]', { fireOnAttributesModification: true, existing: true }, v => { if (!v.parentNode.parentNode) return; const vP = v.parentNode; const vPP = v.parentNode.parentNode; const imagus = !v.hasAttribute('controls') && $('html > div[style*="z-index: 2147483647"]') === v.parentNode; const vidOrParentsIdOrClass = `${v.id}${v.classList}${vP.id}${vP.classList}${vPP.id}${vPP.classList}`; const exclude = v.classList.contains('custom-video-player') || v.classList.contains('imagus') || /(v(ideo)?|me)(-|_)?js|jw|jplay|plyr|kalt|flowp|wisti/i.test(vidOrParentsIdOrClass); if (imagus || v.hasAttribute('controls') && !exclude) { if (imagus) v.classList.add('imagus'); v.classList.add('custom-video-player'); v.classList.add('custom-video-player-hidden'); v.setAttribute('tabindex', '0'); v.setAttribute('preload', 'auto'); v.removeAttribute('controls'); customPlayer(v); } }); }());