Управление громкостью на pzdcflix.live: правая кнопка мыши + колесо
ეს სკრიპტი არ უნდა იყოს პირდაპირ დაინსტალირებული. ეს ბიბლიოთეკაა, სხვა სკრიპტებისთვის უნდა ჩართეთ მეტა-დირექტივაში // @require https://update.greasyfork.org/scripts/588222/1882996/Pzdcflix%20Volume%20Control%20-%20Right%20Click%20%2B%20Wheel.js.
// ==UserScript==
// @name Pzdcflix Volume Control - Right Click + Wheel
// @namespace http://tampermonkey.net/
// @version 2.1.1
// @description Управление громкостью на pzdcflix.live: правая кнопка мыши + колесо
// @author YOSS
// @match https://pzdcflix.live/*
// @grant none
// @resource JetBrainsMono https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700&display=swap
// ==/UserScript==
(function() {
'use strict';
let volumeStep = 0.05;
let volumeDisplay = null;
let hideTimeout = null;
let isRightButtonPressed = false;
let isOverPlayer = false;
// Подключаем шрифт JetBrains Mono
function loadFont() {
const link = document.createElement('link');
link.href = 'https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700&display=swap';
link.rel = 'stylesheet';
document.head.appendChild(link);
}
// Создаем элемент для отображения громкости
function createVolumeDisplay() {
volumeDisplay = document.createElement('div');
volumeDisplay.id = 'volume-control-display';
volumeDisplay.style.cssText = `
position: fixed;
top: 25%;
left: 50%;
transform: translate(-50%, -50%);
color: rgba(220, 220, 220, 0.9);
padding: 10px 20px;
font-size: 20px;
font-family: 'JetBrains Mono', monospace;
font-weight: 400;
z-index: 999999;
pointer-events: none;
display: none;
text-align: center;
text-shadow: 1px 1px 3px rgba(0, 0, 0, 0.4);
letter-spacing: 1px;
transition: opacity 0.2s ease;
`;
document.body.appendChild(volumeDisplay);
}
// Показать уровень громкости
function showVolume(volume) {
if (!volumeDisplay) createVolumeDisplay();
const volumePercent = Math.round(volume * 100);
// Позиционируем индикатор относительно проигрывателя
const video = getActiveVideo();
if (video) {
const player = getPlayerContainer(video);
if (player) {
const rect = player.getBoundingClientRect();
volumeDisplay.style.top = `${rect.top + rect.height * 0.25}px`;
volumeDisplay.style.left = `${rect.left + rect.width / 2}px`;
}
}
// Добавляем плавное появление
volumeDisplay.style.opacity = '0';
volumeDisplay.textContent = `${volumePercent}%`;
volumeDisplay.style.display = 'block';
requestAnimationFrame(() => {
volumeDisplay.style.opacity = '1';
});
clearTimeout(hideTimeout);
hideTimeout = setTimeout(() => {
volumeDisplay.style.opacity = '0';
setTimeout(() => {
volumeDisplay.style.display = 'none';
}, 200);
}, 1500);
}
// Найти активный видеоэлемент
function getActiveVideo() {
const videos = document.querySelectorAll('video');
for (let video of videos) {
if (!video.paused && video.readyState >= 2) {
return video;
}
}
for (let video of videos) {
if (video.offsetParent !== null) {
return video;
}
}
return videos[0] || null;
}
// Найти контейнер проигрывателя
function getPlayerContainer(video) {
if (!video) return null;
const selectors = [
'.player-container',
'.video-container',
'.video-wrapper',
'.video-player',
'.player-wrapper',
'#player',
'#video-player',
'[class*="player"]',
'[class*="video-container"]',
'[id*="player"]'
];
for (let selector of selectors) {
const container = video.closest(selector);
if (container) return container;
}
let element = video.parentElement;
let bestMatch = video;
let maxArea = 0;
while (element && element !== document.body && element !== document.documentElement) {
const rect = element.getBoundingClientRect();
const area = rect.width * rect.height;
if (rect.width >= 400 && rect.height >= 300 && area > maxArea) {
const bodyRect = document.body.getBoundingClientRect();
if (rect.width < bodyRect.width * 0.9 || rect.height < bodyRect.height * 0.9) {
bestMatch = element;
maxArea = area;
}
}
element = element.parentElement;
}
return bestMatch;
}
// Проверяем, находится ли курсор над проигрывателем
function isCursorOverPlayer(event) {
const video = getActiveVideo();
if (!video) return false;
const player = getPlayerContainer(video);
if (!player) return false;
const rect = player.getBoundingClientRect();
const mouseX = event.clientX;
const mouseY = event.clientY;
return mouseX >= rect.left &&
mouseX <= rect.right &&
mouseY >= rect.top &&
mouseY <= rect.bottom;
}
// Изменение громкости
function changeVolume(deltaY) {
const video = getActiveVideo();
if (!video) return false;
const oldVolume = video.volume;
let newVolume;
if (deltaY > 0) {
newVolume = Math.max(0, oldVolume - volumeStep);
} else {
newVolume = Math.min(1, oldVolume + volumeStep);
}
if (newVolume !== oldVolume) {
video.volume = newVolume;
showVolume(newVolume);
try {
localStorage.setItem('pzdcflix_volume', newVolume);
} catch (e) {}
return true;
}
return false;
}
// Восстановление громкости
function restoreVolume(video) {
if (!video) video = getActiveVideo();
if (!video) return;
const savedVolume = localStorage.getItem('pzdcflix_volume');
if (savedVolume !== null) {
video.volume = parseFloat(savedVolume);
}
}
// Настройка обработчиков
function setupEventHandlers() {
document.addEventListener('mousemove', function(e) {
isOverPlayer = isCursorOverPlayer(e);
});
document.addEventListener('contextmenu', function(e) {
if (isRightButtonPressed && isOverPlayer) {
e.preventDefault();
e.stopPropagation();
return false;
}
}, true);
document.addEventListener('mousedown', function(e) {
if (e.button === 2 && isCursorOverPlayer(e)) {
isRightButtonPressed = true;
e.preventDefault();
e.stopPropagation();
const video = getActiveVideo();
if (video) {
showVolume(video.volume);
}
}
}, true);
document.addEventListener('mouseup', function(e) {
if (e.button === 2) {
isRightButtonPressed = false;
clearTimeout(hideTimeout);
if (volumeDisplay) {
volumeDisplay.style.opacity = '0';
setTimeout(() => {
volumeDisplay.style.display = 'none';
}, 200);
}
}
}, true);
document.addEventListener('wheel', function(e) {
if (isRightButtonPressed && isOverPlayer) {
e.preventDefault();
e.stopPropagation();
if (changeVolume(e.deltaY)) {
clearTimeout(hideTimeout);
hideTimeout = setTimeout(() => {
if (volumeDisplay) {
volumeDisplay.style.opacity = '0';
setTimeout(() => {
volumeDisplay.style.display = 'none';
}, 200);
}
}, 1500);
}
}
}, { passive: false, capture: true });
document.addEventListener('mouseleave', function() {
if (isRightButtonPressed) {
isRightButtonPressed = false;
isOverPlayer = false;
if (volumeDisplay) {
volumeDisplay.style.display = 'none';
}
}
});
window.addEventListener('blur', function() {
isRightButtonPressed = false;
isOverPlayer = false;
if (volumeDisplay) {
volumeDisplay.style.display = 'none';
}
});
}
// Настройка наблюдения за DOM
function setupObservers() {
const observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
mutation.addedNodes.forEach(function(node) {
if (node.nodeName === 'VIDEO') {
node.addEventListener('play', function() {
restoreVolume(node);
});
restoreVolume(node);
}
if (node.querySelectorAll) {
const videos = node.querySelectorAll('video');
videos.forEach(function(video) {
video.addEventListener('play', function() {
restoreVolume(video);
});
restoreVolume(video);
});
}
});
});
});
observer.observe(document.body, {
childList: true,
subtree: true
});
setInterval(() => {
const video = getActiveVideo();
if (video) restoreVolume(video);
}, 2000);
}
// Инициализация
function init() {
loadFont();
setupEventHandlers();
setupObservers();
setTimeout(() => {
const video = getActiveVideo();
if (video) {
restoreVolume(video);
}
}, 1000);
}
// Запускаем после полной загрузки страницы
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
})();