let imagusAudio; let audioSync; let audioError; let ytID; let ytTimeChecked; const $ = document.querySelector.bind(document); const $$ = document.querySelectorAll.bind(document); const newEl = document.createElement.bind(document); const settings = { // delay to hide contols and cursor if inactive (set to 3000 milliseconds) hideControls: 3000, // 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 shortcutFuncs = { toggleCaptions: v => { const validTracks = []; for (let i = 0; i < v.textTracks.length; ++i) { 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; function cleanup(e) { for (let i = 0; i < v.textTracks.length; ++i) { const ott = v.textTracks[i]; if (ott.mode === 'showing') { delete v.cbhtml5vsLastCaptionTrack; v.textTracks.removeEventListener('change', cleanup); return; } } } v.textTracks.addEventListener('change', cleanup); } return; } else 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; } else 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; } else 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; } else if (bPre === navPre && aPre !== navPre) { return 1; } return 0; })[0].mode = 'showing'; }, togglePlay: v => { v.paused ? v.play() : 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 { v.volume <= 0.9 ? v.volume = increase : 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); v.volume >= 0.1 ? v.volume = decrease : 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 keyFuncs = { 32: shortcutFuncs.togglePlay, // Space 75: shortcutFuncs.togglePlay, // K 35: shortcutFuncs.toEnd, // End 48: shortcutFuncs.toStart, // 0 36: shortcutFuncs.toStart, // Home 37: shortcutFuncs.skipLeft, // Left arrow 74: shortcutFuncs.skipLeft, // J 39: shortcutFuncs.skipRight, // Right arrow 76: shortcutFuncs.skipRight, // L 38: shortcutFuncs.increaseVol, // Up arrow 40: shortcutFuncs.decreaseVol, // Down arrow 77: shortcutFuncs.toggleMute, // M 70: shortcutFuncs.toggleFS, // F 67: shortcutFuncs.toggleCaptions, // C 82: shortcutFuncs.reloadVideo, // R 188: shortcutFuncs.slowOrPrevFrame, // Comma or Less-Than 190: shortcutFuncs.fastOrNextFrame, // Period or Greater-Than 191: shortcutFuncs.normalSpeed, // Forward slash or ? 49: shortcutFuncs.toPercentage, // 1 50: shortcutFuncs.toPercentage, // 2 51: shortcutFuncs.toPercentage, // 3 52: shortcutFuncs.toPercentage, // 4 53: shortcutFuncs.toPercentage, // 5 54: shortcutFuncs.toPercentage, // 6 55: shortcutFuncs.toPercentage, // 7 56: shortcutFuncs.toPercentage, // 8 57: shortcutFuncs.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 target; let clickCount = 0; let repeat = 0; const directVideo = /video/.test(document.contentType) && document.body.firstElementChild === v; const controls = newEl('controls'); const imagus = v.classList.contains('imagus'); if (imagus && !imagusVid) { imagusVid = v; imagusAudio = newEl('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; self === top ? document.body.classList.add('direct-video-top-level') : document.body.classList.add('direct-video-embed'); } else { elToFocus = v; videoWrapper = newEl('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 = newEl('btn'); playButton.className = 'toggle-play'; controls.appendChild(playButton); const beginButton = newEl('btn'); beginButton.className = 'begin'; controls.appendChild(beginButton); const skipLongLeft = newEl('btn'); skipLongLeft.className = 'skip-long left'; controls.appendChild(skipLongLeft); const skipShortLeft = newEl('btn'); skipShortLeft.className = 'skip-short left'; controls.appendChild(skipShortLeft); const skipShortRight = newEl('btn'); skipShortRight.className = 'skip-short right'; controls.appendChild(skipShortRight); const skipLongRight = newEl('btn'); skipLongRight.className = 'skip-long right'; controls.appendChild(skipLongRight); const timelineWrapper = newEl('timelinewrapper'); controls.appendChild(timelineWrapper); const currentTime = newEl('currenttime'); currentTime.textContent = '0:00'; timelineWrapper.appendChild(currentTime); const timeline = newEl('timeline'); timelineWrapper.appendChild(timeline); const timeBar = newEl('timebar'); timeline.appendChild(timeBar); const timeBuffer = newEl('timebuffer'); timeBar.appendChild(timeBuffer); const timeProgress = newEl('timeprogress'); timeBar.appendChild(timeProgress); const timeSlider = newEl('input'); timeSlider.type = 'range'; timeSlider.value = 0; timeSlider.min = 0; timeSlider.max = 100; timeSlider.step = 0.01; timeSlider.textContent = ''; timeline.appendChild(timeSlider); const timeTooltip = newEl('timetooltip'); timeTooltip.className = 'hidden'; timeline.appendChild(timeTooltip); const preview = newEl('preview'); timeTooltip.appendChild(preview); const timeText = newEl('timetext'); timeTooltip.appendChild(timeText); timeText.textContent = '-:-'; const totalTime = newEl('totaltime'); totalTime.textContent = '-:-'; timelineWrapper.appendChild(totalTime); const rateDecrease = newEl('btn'); rateDecrease.className = 'rate-decrease'; controls.appendChild(rateDecrease); const rate = newEl('rate'); rate.textContent = '1x'; controls.appendChild(rate); const rateIncrease = newEl('btn'); rateIncrease.className = 'rate-increase'; controls.appendChild(rateIncrease); const volume = newEl('volume'); controls.appendChild(volume); const volumeBar = newEl('volumebar'); volume.appendChild(volumeBar); const volumeTrail = newEl('volumetrail'); volumeBar.appendChild(volumeTrail); const volumeSlider = newEl('input'); volumeSlider.type = 'range'; volumeSlider.min = 0; volumeSlider.max = 1; volumeSlider.step = 0.01; volumeSlider.textContent = ''; volume.appendChild(volumeSlider); const volumeTooltip = newEl('volumetooltip'); volumeTooltip.className = 'hidden'; volumeTooltip.textContent = '0%'; volume.appendChild(volumeTooltip); const muteButton = newEl('btn'); muteButton.className = 'mute'; controls.appendChild(muteButton); const expandButton = newEl('btn'); expandButton.className = 'expand'; controls.appendChild(expandButton); v.classList.remove('custom-native-player-hidden'); if (v.querySelector('source')) v.classList.add('contains-source'); if (videoWrapper) enforcePosition(); volumeValues(); v.onloadedmetadata = e => { loaded = true; shortcutFuncs.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(e); }; v.onloadeddata = () => { const imagusVreddit = /v(cf)?\.redd\.it/.test(v.src); const vHasAudio = hasAudio(v); 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 native player reloaded'); } }; v.onseeked = () => { styleBuffer(); setTimeout(styleBuffer, 500); }; v.onprogress = () => { styleBuffer(); setTimeout(styleBuffer, 500); }; v.ontimeupdate = e => { if (v.readyState > 0) { if (v.duration > 0 && !mouseDown) { sliderValues(e); totalTime.textContent = formatTime(v.duration); if (!imagus && savedTimeKey) localStorage.setItem(savedTimeKey, v.currentTime); } } }; v.onvolumechange = e => { 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(e); v.volume > 0.1 ? localStorage.setItem('videovolume', v.volume) : 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) { const vPP = v.parentNode.parentNode; if (imagusAudio.getAttribute('src') && /v(cf)?\.redd\.it/.test(imagusAudio.src)) { audioSync = false; audioError = false; imagusAudio.pause(); imagusAudio.removeAttribute('src'); imagusAudio.load(); imagusAudio.removeAttribute('loop'); } if (v.src !== '') { if (/\.(mp3|m4a)/.test(v.src)) { vPP.classList.add('audio-only'); } if (/v(cf)?\.redd\.it/.test(v.src)) { const prefix = v.src.split('DASH')[0].replace('vcf.', 'v.'); const audioSrc = `${prefix}DASH_AUDIO_128.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'); } vPP.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'); vPP.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++; const checkState = v.paused; if (clickCount === 1) { setTimeout(() => { if (clickCount === 1) { // avoid conflicts with existing click listeners const recheckState = v.paused; if (checkState === recheckState) shortcutFuncs.togglePlay(v); } else { shortcutFuncs.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 = () => { controlsTimeout ? clearTimeout(controlsTimeout) : 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.onmousedown = e => { if (e.button > 0) return; target = e.target; }; controls.onmouseup = () => { if (error) return; elToFocus.focus({preventScroll: true}); target = null; }; timeSlider.onmousemove = e => sliderValues(e); timeSlider.oninput = e => sliderValues(e); 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 || e.target !== target) return; mouseDown = false; isSeeking = false; if (v.readyState > 0) { sliderValues(e); if (isPlaying) { v.play(); isPlaying = false; } } }; volumeSlider.onmousemove = e => sliderValues(e); volumeSlider.oninput = e => { if (v.muted) shortcutFuncs.toggleMute(v); sliderValues(e); }; muteButton.onmouseup = e => { if (e.button > 0 || e.target !== target) return; const lastVolume = localStorage.getItem('videovolume'); if (v.muted || v.volume) shortcutFuncs.toggleMute(v); v.volume = lastVolume; if (audioSync) imagusAudio.muted = v.muted; }; playButton.onmouseup = e => { if (e.button > 0 || e.target !== target) return; shortcutFuncs.togglePlay(v); }; skipShortLeft.onmouseup = e => { if (e.button > 0 || e.target !== target) return; shortcutFuncs.skipLeft(v); }; skipShortRight.onmouseup = e => { if (e.button > 0 || e.target !== target) return; shortcutFuncs.skipRight(v); }; skipLongLeft.onmouseup = e => { if (e.button > 0 || e.target !== target) return; v.currentTime -= settings.skipShift; }; skipLongRight.onmouseup = e => { if (e.button > 0 || e.target !== target) return; v.currentTime += settings.skipShift; }; beginButton.onmouseup = e => { if (e.button > 0 || e.target !== target) return; v.currentTime = 0; timeSlider.value = 0; timeProgress.style.width = '0'; currentTime.textContent = '0:00'; }; rateDecrease.onmouseup = e => { if (e.button > 0 || e.target !== target) return; shortcutFuncs.slowOrPrevFrame(v); }; rateIncrease.onmouseup = e => { if (e.button > 0 || e.target !== target) return; shortcutFuncs.fastOrNextFrame(v); }; rate.onmouseup = e => { if (e.button > 0 || e.target !== target) return; shortcutFuncs.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 || e.target !== target) return; shortcutFuncs.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(v); 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(e) { let slider; let xPosition; const vid = audioSync ? imagusAudio && v : v; const eType = e && e.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 || !e) { slider = eMeta || eTime ? timeSlider : volumeSlider; } else { slider = e.target; } const tooltip = slider.nextSibling; const timeTarget = slider === timeSlider; const sliderWidth = slider.clientWidth; const halfSlider = sliderWidth / 2; const slider14ths = halfSlider / 7; const eX = e && e.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 || !e) { xPosition = eMeta || eTime ? ((((100 / v.duration) * v.currentTime) * sliderWidth) / 100).toFixed(1) : (v.volume * sliderWidth).toFixed(1); } if (eTime && e.target === imagusVid && audioSync) { if (imagusVid.currentTime - imagusAudio.currentTime >= 0.1 || imagusVid.currentTime - imagusAudio.currentTime <= -0.1) { imagusAudio.currentTime = imagusVid.currentTime + 0.06; console.log('time sync corrected'); if (muteTillSync && imagusAudio.readyState > 2) { imagusAudio.muted = false; muteTillSync = false; console.log('unmuted after time correct'); } } else if (muteTillSync && imagusAudio.readyState > 2) { imagusAudio.muted = false; muteTillSync = false; console.log('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 || !e) { 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; timeText.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.dataset.targetTime = time; tooltip.style.left = `${eX}px`; if (v.readyState > 0 && timeTarget) timeText.textContent = formatTime(time); if (!timeTarget) tooltip.textContent = `${xPosPercent}%`; } tooltip.classList.remove('hidden'); preventMouseMove = false; } } function styleBuffer() { if (v.readyState > 1 && v.duration > 0) { const buffer = (v.buffered.end(v.buffered.length - 1) / v.duration) * 100; timeBuffer.style.width = `${buffer}%`; } } function formatTime(t) { if (isNaN(t)) { timeTooltip.classList.add('hidden'); return '-:-'; } else { 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) return; if (width < 892) { v.classList.add('compact'); if (imagus) v.parentNode.parentNode.classList.add('compact'); } else { v.classList.remove('compact'); if (imagus) v.parentNode.parentNode.classList.remove('compact'); } width < 412 ? v.classList.add('compact-2') : v.classList.remove('compact-2'); width < 316 ? v.classList.add('compact-3') : v.classList.remove('compact-3'); width < 246 ? v.classList.add('compact-4') : 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 = keyFuncs[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 = keyFuncs[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 = keyFuncs[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 = keyFuncs[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) { bs[i].remove(); } } repeat++; if (repeat < 10) enforcePosition.call(this); }, 100); } } function ytSaveCurrentTime(v) { v.addEventListener('loadstart', ytCheckSavedTime); v.addEventListener('loadeddata', ytCheckSavedTime); v.ontimeupdate = () => { if (v.currentTime > 0 && ytTimeChecked) localStorage.setItem(ytID, v.currentTime); }; v.onended = () => { if (localStorage.getItem(ytID)) localStorage.removeItem(ytID); }; } function ytCheckSavedTime(e) { ytID = location.href.replace(/.*?\/(watch\?v=|embed\/)(.*?)(\?|&|$).*/, '$2'); const savedTime = localStorage.getItem(ytID); const timeURL = /(\?|&)(t(ime_continue)?|start)=[1-9]/.test(location.href); const ytStart = $('.ytp-clip-start:not([style*="left: 0%;"])'); if (e.type === 'loadstart') { ytTimeChecked = false; if ((!ytStart || !savedTime) && !timeURL) ytTimeChecked = true; if (ytStart) ytStart.click(); if (ytTimeChecked && savedTime) e.target.currentTime = savedTime; e.target.focus({preventScroll: true}); if (self === top) window.scroll({top: 0, behavior: 'smooth'}); } else if (e.type === 'loadeddata' && !ytTimeChecked) { if (savedTime) e.target.currentTime = savedTime; ytTimeChecked = true; } } function moveStyle() { const style = $('#custom-native-player-style'); if (!style) return; const docEls = $$('html > *'); for (let i = 0; i < docEls.length; i++) { if (docEls[i].tagName === 'STYLE' && docEls[i].classList.contains('stylus') && docEls[i].id !== 'custom-native-player-style') { $('html').insertBefore(style, docEls[i]); break; } else if (docEls[i] === docEls[docEls.length - 1]) { $('html').insertBefore(style, docEls[i].nextSibling); } } } window.addEventListener('DOMContentLoaded', () => { const style = $('#custom-native-player-style'); !style ? injectStyle() : moveStyle(); setTimeout(moveStyle, 1000); 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-native-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-native-player'); v.classList.add('custom-native-player-hidden'); v.setAttribute('tabindex', '0'); v.setAttribute('preload', 'auto'); v.removeAttribute('controls'); customPlayer(v); } }); }); if (/^https?:\/\/www\.youtube\.com/.test(location.href)) { document.arrive( '#player video[src*="youtube.com"]', {fireOnAttributesModification: true, existing: true}, v => { ytSaveCurrentTime(v); }); } const css = `.imagus-video-wrapper { 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: hsl(0, 0%, 0%)!important; width: calc(100% - 100px)!important; } .imagus-video-wrapper.stickied { box-shadow: 0 0 0 100000px hsla(0, 0%, 0%, .7)!important; } html > div[style*="2147483647"] div span { cursor: auto!important; } .imagus-video-wrapper videowrapper { height: 0!important; padding-top: 56.25%!important; } .imagus-video-wrapper videowrapper video.custom-native-player { position: absolute!important; } @media (min-width: 177.778vh) { .imagus-video-wrapper { margin: 18px auto!important; height: calc(100vh - 18px)!important; width: calc(((100vh - 18px) * 16) / 9)!important; } .imagus-video-wrapper videowrapper { height: 100%!important; padding-top: 0!important; } .imagus-video-wrapper videowrapper video.custom-native-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: hsl(0, 0%, 90%)!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-native-player + controls, video[controls]:not(.custom-native-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: 0px!important; top: 0!important; bottom: 0!important; left: 0!important; right: 0!important; background-color: hsl(0, 0%, 0%)!important; overflow: hidden!important; } video.custom-native-player + controls timetooltip, video.custom-native-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: hsla(0, 0%, 0%, .7)!important; box-shadow: 0 0 4px hsla(0, 0%, 100%, .5)!important; color: hsl(0, 0%, 100%)!important; pointer-events: none!important; } video.custom-native-player + controls timetooltip timetext { color: hsl(0, 0%, 100%)!important; } video.custom-native-player + controls timetooltip.preview preview { height: 113px!important; width: 200px!important; display: block!important; } video.custom-native-player + controls timetooltip.preview { height: 138px!important; width: 200px!important; top: -142px!important; margin-left: -100px!important; } video.custom-native-player + controls timetooltip { margin-left: -25px!important; width: 50px!important; } video.custom-native-player + controls volumetooltip { margin-left: -20px!important; width: 40px!important; } video.custom-native-player.compact + controls timeline timetooltip { top: -25px!important; } video.custom-native-player.compact + controls btn, video.custom-native-player.compact + controls rate, video.custom-native-player.compact + controls volume { height: 24px!important; line-height: 22px!important; } video.custom-native-player.compact + controls volume input { padding-bottom: 2px!important; } video.custom-native-player.compact + controls btn:before { margin-top: -2px!important; } video.custom-native-player.compact + controls volume > volumebar { top: 6px!important; } video.custom-native-player + controls timelinewrapper { height: 100%!important; line-height: 20px!important; } video.custom-native-player + controls timeline:hover timetooltip:not(.hidden), video.custom-native-player + controls volume:hover volumetooltip:not(.hidden) { display: inline!important; } video.custom-native-player { user-select: none!important; 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: hsl(0, 0%, 0%)!important; border-radius: 0!important; } video.custom-native-player:not(.contains-source):not([src*="/"]) { cursor: auto!important; } video.custom-native-player:not(.contains-source):not([src*="/"]) + controls { display: none!important; } video.custom-native-player + controls > * { background: none!important; outline: none!important; line-height: 32px!important; font-family: monospace!important; } video.custom-native-player.compact + controls > * { line-height: 24px!important; } video.custom-native-player + controls { --controls-z-index: 1; white-space: nowrap!important; transition: opacity .5s ease 0s!important; background-color: hsla(0, 0%, 0%, .85)!important; height: 32px !important; width: 100%!important; cursor: default !important; font-size: 18px !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-native-player.custom-native-player-hidden, video.custom-native-player.custom-native-player-hidden + controls { opacity: 0!important; pointer-events: none!important; } video.custom-native-player.paused + controls, video.custom-native-player.active + controls, video.custom-native-player + controls:hover { opacity: 1!important; } video.custom-native-player + controls timeline { flex-grow: 1!important; position: relative!important; align-items: center!important; flex-direction: column!important; height: 100%!important; } video.custom-native-player + controls timelinewrapper { flex: 1 0 480px!important; position: relative!important; align-items: center!important; } video.custom-native-player.compact + controls timelinewrapper { order: -1; flex-basis: 100%!important; height: 20px!important; } video.custom-native-player.compact + controls timeline timebar { top: 5px!important; } video.custom-native-player.compact + controls currenttime, video.custom-native-player.compact + controls totaltime { line-height: 20px!important; } video.custom-native-player.compact + controls { height: 44px!important; } video.custom-native-player.compact-2 + controls btn.begin, video.custom-native-player.compact-2 + controls btn.skip-short, video.custom-native-player.compact-3 + controls rate, video.custom-native-player.compact-3 + controls btn.rate-increase, video.custom-native-player.compact-3 + controls btn.rate-decrease, video.custom-native-player.compact-4 + controls btn.skip-long { display: none!important; } video.custom-native-player + controls > * { display: inline-flex!important; } video.custom-native-player.compact-2 + controls btn.rate-increase, video.custom-native-player.compact-4 + controls btn.toggle-play { margin-right: auto!important; } video.custom-native-player + controls timeline > timebar > timebuffer, video.custom-native-player + controls timeline > timebar > timeprogress, video.custom-native-player + controls volume > volumebar > volumetrail { position: absolute!important; flex: none!important; pointer-events: none!important; height: 100%!important; border-radius: 20px!important; } video.custom-native-player + controls timeline > timebar, video.custom-native-player + controls volume > volumebar { position: absolute!important; height: 10px!important; border-radius: 20px!important; overflow: hidden!important; background-color: hsla(0, 0%, 16%, .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 hsla(0, 0%, 40%), inset 0 0 5px hsla(0, 0%, 40%, .85)!important; } .audio-only.imagus-video-wrapper { height: 58px!important; padding: 0!important; } .audio-only.imagus-video-wrapper.compact { height: 78px!important; } .audio-only.imagus-video-wrapper video.custom-native-player + controls { opacity: 1!important; } .audio-only.imagus-video-wrapper video.custom-native-player { height: 0!important; opacity: 0!important; min-height: 0!important; } .audio-only.imagus-video-wrapper.stickied { box-shadow: none!important; } .audio-only.imagus-video-wrapper videowrapper { height: 58px!important; top: auto!important; padding:0!important; } .audio-only.imagus-video-wrapper.compact { top: 18px!important; bottom: auto!important; } .audio-only.imagus-video-wrapper.compact videowrapper { height: 78px!important; } video.custom-native-player + controls volume.disabled, video.custom-native-player + controls btn.disabled { -webkit-filter: brightness(.4); filter: brightness(.4); pointer-events: none!important; } video.custom-native-player.disabled, video.custom-native-player.active.disabled { cursor: default!important; } video.custom-native-player.disabled + controls { opacity: 1!important; -webkit-filter: brightness(.3)sepia(1)hue-rotate(320deg)saturate(5); filter: brightness(.3)sepia(1)hue-rotate(320deg)saturate(5); } video.custom-native-player.disabled + controls > * { pointer-events: none!important; } video.custom-native-player + controls volume { max-width: 70px!important; flex: 1 0 48px!important; position: relative!important; margin: 0 12px!important; height: 100%!important; } video.custom-native-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-native-player + controls timeline > timebar > timeprogress, video.custom-native-player + controls volume > volumebar > volumetrail { background-color: hsla(0, 0%, 100%, .4)!important; left: 0!important; } video.custom-native-player + controls volume.disabled volumetrail { width: 0!important; } video.custom-native-player + controls timeline > input { height: 100%!important; width: 100%!important; } video.custom-native-player.active { cursor: pointer!important; } video.custom-native-player + controls btn { border: none !important; cursor: pointer!important; background-color: transparent!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: content-box!important; position: relative!important; opacity: .86!important; text-shadow: none!important; transition: opacity .3s, text-shadow .3s!important; -webkit-text-fill-color: hsl(0, 0%, 100%)!important; } video.custom-native-player + controls btn.toggle-play { flex: 1 1 46px!important } video.custom-native-player + controls btn:hover { opacity: 1!important; text-shadow: 0 0 8px hsla(0, 0%, 100%)!important; } video.custom-native-player.playback-rate-increased + controls btn.rate-increase, video.custom-native-player.playback-rate-decreased + controls btn.rate-decrease { -webkit-text-fill-color: cyan!important; } video.custom-native-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: bold!important; letter-spacing: .5px!important; -webkit-text-fill-color: hsl(0, 0%, 100%)!important; user-select: none!important; pointer-events: none!important; opacity: .86!important; } video.custom-native-player + controls rate[data-current-rate] { pointer-events: all!important; cursor: pointer!important; } video.custom-native-player + controls rate[data-current-rate]:hover { transition: opacity .3s, text-shadow .3s!important; opacity: 1!important; text-shadow: 0 0 8px hsla(0, 0%, 100%)!important; } video.custom-native-player + controls input[type=range] { -webkit-appearance: none!important; background-color: transparent !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; height: 100%!important; width: 100%!important; position: relative!important; } video.custom-native-player + controls input[type='range']::-webkit-slider-thumb { -webkit-appearance: none!important; background-color: hsl(0, 0%, 86%)!important; border: 0!important; height: 14px!important; width: 14px!important; border-radius: 50%!important; pointer-events: none!important; } video.custom-native-player.muted + controls volume input[type='range']::-webkit-slider-thumb { background-color: hsl(0, 0%, 50%)!important; } video.custom-native-player + controls input[type='range']::-moz-range-thumb { -moz-appearance: none!important; background-color: hsl(0, 0%, 86%)!important; border: 0!important; height: 14px!important; width: 14px!important; border-radius: 50%!important; pointer-events: none!important; } video.custom-native-player.muted + controls volume input[type='range']::-moz-range-thumb { background-color: hsl(0, 0%, 50%)!important; } video.custom-native-player + controls currenttime, video.custom-native-player + controls totaltime { font-family: monospace, arial!important; font-weight: bold!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: hsl(0, 0%, 86%)!important; } video.custom-native-player + controls btn.rate-decrease, video.custom-native-player + controls btn.rate-increase { padding: 0!important; flex: 1 0 14px!important; max-width: 24px!important; } video.custom-native-player + controls btn.rate-decrease { margin-left: auto!important; } video.custom-native-player + controls currenttime { padding: 0 12px 0 0!important; margin-right: 2px!important; text-align: right!important; } video.custom-native-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(((100vw - 30px) * 9) / 16)!important; min-height: calc(((100vw - 30px) * 9) / 16)!important; max-height: calc(((100vw - 30px) * 9) / 16)!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-native-player + controls { position: absolute!important; left: 0!important; right: 0!important; margin: 0 auto !important; width: calc(100vw - 30px)!important; bottom: calc((100vh - (((100vw - 30px) * 9) / 16)) / 2)!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; width: calc(((100vh - 30px) * 16) / 9)!important; min-width: calc(((100vh - 30px) * 16) / 9)!important; max-width: calc(((100vh - 30px) * 16) / 9)!important; margin: 8px auto 0!important; padding: 0!important; background-color: hsl(0, 0%, 0%)!important; } .direct-video-top-level > video.custom-native-player + controls { width: calc(((100vh - 30px) * 16) / 9)!important; min-width: calc(((100vh - 30px) * 16) / 9)!important; max-width: calc(((100vh - 30px) * 16) / 9)!important; bottom: 15px!important; } } video::-webkit-media-controls, .native-fullscreen > *:not(video):not(controls) { display: none!important; } .native-fullscreen video.custom-native-player, .direct-video-top-level .native-fullscreen video.custom-native-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-native-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-native-player + controls btn:before { font-family: 'customNativePlayer'!important; font-weight: 400!important; -webkit-font-smoothing: subpixel-antialiased!important; -moz-osx-font-smoothing: subpixel-antialiased!important; font-size: 20px!important; } video.custom-native-player + controls btn.skip-short.right:before { content: '\\e90c'!important; } video.custom-native-player + controls btn.skip-short.left:before { content: '\\e90b'!important; } video.custom-native-player + controls btn.skip-long.right:before { content: '\\e901'!important; } video.custom-native-player + controls btn.skip-long.left:before { content: '\\e902'!important; } video.custom-native-player + controls btn.begin:before { content: '\\e908'!important; } video.custom-native-player + controls btn.toggle-play:before { content: '\\e906'!important; font-size: 26px!important; } video.custom-native-player.playing + controls btn.toggle-play:before { content: '\\e905'!important; font-size: 24px!important; } video.custom-native-player + controls btn.rate-decrease:before { content: '\\ea0b'!important; font-size: 10px!important; } video.custom-native-player + controls btn.rate-increase:before { content: '\\ea0a'!important; font-size: 10px!important; } video.custom-native-player + controls btn.mute:before { content: '\\e90a'!important; font-size: 22px!important; } video.custom-native-player.muted + controls btn.mute:before { content: '\\e909'!important; font-size: 22px!important; } video.custom-native-player + controls btn.mute.disabled:before { content: '\\e909'!important; } video.custom-native-player + controls btn.expand:before { content: '\\e904'!important; font-size: 24px!important; } .native-fullscreen video.custom-native-player + controls btn.expand:before { content: '\\e903'!important; font-size: 24px!important; } @font-face { font-family: 'customNativePlayer'; src: url(data:application/x-font-woff;charset=utf-8;base64,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) format('woff'), url('customNativePlayer.ttf') format('truetype'), url('customNativePlayer.svg#customNativePlayer') format('svg'); font-weight: normal; font-style: normal; }`; function injectStyle() { const style = newEl('style'); style.id = 'custom-native-player-style'; style.type = 'text/css'; style.className = 'stylus'; // Dark Reader won't brute force override stylus style.textContent = css; document.documentElement.appendChild(style); } injectStyle();