您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Tua, auto next, menu nổi khi xem phim trên hoathinh3d.gg/xem-phim
// ==UserScript== // @name HH3D Video Player - Lệ Phi Vũ // @namespace http://tampermonkey.net/ // @version 1.0 // @description Tua, auto next, menu nổi khi xem phim trên hoathinh3d.gg/xem-phim // @match https://hoathinh3d.gg/xem-phim* // @author Lệ Phi Vũ // @grant GM_setValue // @grant GM_getValue // ==/UserScript== (function () { 'use strict'; // === Load từ localStorage const savedSec = localStorage.getItem("vh_seek_sec") || "60"; const savedPercent = localStorage.getItem("vh_auto_next") || "95"; const style = ` #vh-menu { position: fixed; top: 100px; left: 20px; background: rgba(0, 0, 0, 0.9); color: gold; padding: 10px; border-radius: 12px; z-index: 999999; font-family: Arial, sans-serif; user-select: none; min-width: 200px; } #vh-menu h3 { margin: 0; font-size: 14px; cursor: pointer; text-align: center; border-bottom: 1px solid gold; border-radius: 12px; padding-bottom: 4px; } #vh-body { margin-top: 6px; } #vh-body.hidden { display: none; } #vh-body input { width: 60px; background: black; color: gold; border: 1px solid gold; border-radius: 4px; margin-left: 5px; } `; const styleTag = document.createElement('style'); styleTag.innerHTML = style; document.head.appendChild(styleTag); const menu = document.createElement('div'); menu.id = 'vh-menu'; menu.innerHTML = ` <h3 id="vh-title">🎬 HH3D Xem Phim</h3> <div id="vh-body"> <div> Tua đến (giây): <input id="vh-seek-sec" type="number" min="0" value="${savedSec}"> </div> <div> Auto Next (%): <input id="vh-next-percent" type="number" min="0" max="100" value="${savedPercent}"> </div> </div> `; document.body.appendChild(menu); // === Cập nhật nhãn tên phim + tập + tiến trình function updateTitle() { const titleEl = document.querySelector('h1.entry-title a'); const video = getVideo(); let titleText = '🎬 HH3D Xem Phim'; if (titleEl) { const fullTitle = titleEl.textContent.trim(); const match = fullTitle.match(/(.+?) Tập (\d+)/); if (match) { const name = match[1]; const ep = match[2]; titleText = `📺 ${name} - Tập ${ep}`; } } if (video && video.duration) { const percent = ((video.currentTime / video.duration) * 100).toFixed(0); titleText += ` (${percent}%)`; } document.getElementById('vh-title').textContent = titleText; } // === Thu gọn khi click tiêu đề document.getElementById('vh-title').addEventListener('click', () => { const body = document.getElementById('vh-body'); body.classList.toggle('hidden'); }); // === Lưu khi người dùng thay đổi (chỉ chấp nhận số) document.getElementById('vh-seek-sec').addEventListener('change', e => { const value = parseFloat(e.target.value); if (!isNaN(value) && value >= 0) { localStorage.setItem("vh_seek_sec", value.toString()); } else { e.target.value = localStorage.getItem("vh_seek_sec") || "60"; } }); document.getElementById('vh-next-percent').addEventListener('change', e => { const value = parseFloat(e.target.value); if (!isNaN(value) && value >= 0 && value <= 100) { localStorage.setItem("vh_auto_next", value.toString()); } else { e.target.value = localStorage.getItem("vh_auto_next") || "95"; } }); // === Tìm video function getVideo() { return document.querySelector('video'); } // === Theo dõi thời lượng video và cập nhật tiêu đề setInterval(() => { const video = getVideo(); if (video && video.duration) { const percent = ((video.currentTime / video.duration) * 100).toFixed(1); const threshold = parseFloat(document.getElementById('vh-next-percent').value || "95"); if (percent >= threshold && !video.__nexted) { video.__nexted = true; const nextBtn = document.querySelector('.epfull .active + a'); if (nextBtn) { window.location.href = nextBtn.href; } } updateTitle(); // Cập nhật tiêu đề với tiến trình } }, 1000); // === Tua video đến số giây được chỉ định function seekToSavedTime() { const video = getVideo(); if (video) { const sec = parseFloat(document.getElementById('vh-seek-sec').value); if (!isNaN(sec) && sec >= 0) { video.currentTime = sec; } } } // === Phím tắt document.addEventListener('keydown', (e) => { const video = getVideo(); if (!video) return; switch (e.key) { case '+': { const nextBtn = document.querySelector('.luotxem.halim-next-episode'); if (nextBtn) { nextBtn.click(); setTimeout(seekToSavedTime, 1000); // Chờ video tải rồi tua } break; } case '-': { const prevBtn = document.querySelector('.luotxem.halim-prev-episode'); if (prevBtn) { prevBtn.click(); setTimeout(seekToSavedTime, 1000); // Chờ video tải rồi tua } break; } case '*': { const sec = parseFloat(document.getElementById('vh-seek-sec').value); if (!isNaN(sec) && sec >= 0) video.currentTime = sec; break; } } }); // === Di chuyển menu (hỗ trợ 4 hướng) let isDragging = false; let offsetX = 0, offsetY = 0; const title = document.getElementById('vh-title'); title.addEventListener('mousedown', (e) => { isDragging = true; offsetX = e.clientX - menu.offsetLeft; offsetY = e.clientY - menu.offsetTop; e.preventDefault(); }); document.addEventListener('mouseup', () => isDragging = false); document.addEventListener('mousemove', (e) => { if (isDragging) { menu.style.left = `${e.clientX - offsetX}px`; menu.style.top = `${e.clientY - offsetY}px`; } }); // === Đảm bảo menu hiển thị khi fullscreen const ensureMenuInFullscreen = () => { const fullscreenElement = document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement; if (fullscreenElement && !fullscreenElement.contains(menu)) { fullscreenElement.appendChild(menu); menu.style.zIndex = '999999'; } else if (!document.body.contains(menu)) { document.body.appendChild(menu); } }; // Theo dõi sự kiện thay đổi toàn màn hình document.addEventListener('fullscreenchange', ensureMenuInFullscreen); document.addEventListener('webkitfullscreenchange', ensureMenuInFullscreen); document.addEventListener('mozfullscreenchange', ensureMenuInFullscreen); document.addEventListener('MSFullscreenChange', ensureMenuInFullscreen); // Gọi lần đầu để đảm bảo menu hiển thị đúng ensureMenuInFullscreen(); })();