Lightweight, non-blocking auto-unmute. No page freeze.
// ==UserScript==
// @name Eporner Auto Unmute
// @namespace https://github.com/yourusername
// @version 4.1
// @description Lightweight, non-blocking auto-unmute. No page freeze.
// @author You
// @match *://*.eporner.com/*
// @grant none
// @run-at document-idle
// @license MIT
// ==/UserScript==
(function() {
'use strict';
let finished = false;
let attempts = 0;
const MAX_ATTEMPTS = 12; // ~7 seconds total polling
function tryUnmute() {
if (finished) return;
attempts++;
// 1️⃣ Direct <video> element manipulation (fastest & most reliable)
const video = document.querySelector('video');
if (video) {
if (video.muted) video.muted = false;
if (video.volume < 1.0) video.volume = 1.0;
}
// 2️⃣ Click UI button if it's in the muted state
const muteBtn = document.querySelector('.vjs-mute-control[title="Unmute"], .vjs-mute-control.vjs-vol-0');
if (muteBtn && muteBtn.offsetParent !== null) {
muteBtn.click();
}
// 3️⃣ Video.js API fallback (if available)
if (window.videojs) {
const players = Object.values(window.videojs.players || {});
players.forEach(p => {
try { p.muted(false); p.volume(1.0); } catch(e) {}
});
}
// ✅ Check if we successfully reached the vjs-vol-3 / "Mute" state
const isNowUnmuted = document.querySelector('.vjs-mute-control[title="Mute"], .vjs-mute-control.vjs-vol-3');
if (isNowUnmuted || (video && !video.muted)) {
console.log('[AutoUnmute] ✅ Success: Unmuted & volume set to 100%.');
finished = true;
return;
}
// 🔄 Safe polling loop (yields to main thread between attempts)
if (attempts < MAX_ATTEMPTS) {
setTimeout(tryUnmute, 600);
} else {
console.warn('[AutoUnmute] ⏹️ Stopped. Player may require a manual page click due to browser autoplay policy.');
}
}
// Wait 1s for page assets & player to initialize, then start
setTimeout(tryUnmute, 1200);
})();