您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Replaces fluid player with browsers HTML5 native player, initialises native preload and proceeds full preload in background.
当前为
// ==UserScript== // @name GBT HTML5 native player, full preload, download (GBTPP) // @version 4.8 // @namespace _pc // @description Replaces fluid player with browsers HTML5 native player, initialises native preload and proceeds full preload in background. // @author verydelight // @license MIT // @icon https://www.gayporntube.com/favicon.ico // @connect gayporntube.com // @compatible Firefox Tampermonkey // @grant GM.xmlHttpRequest // @grant GM_download // @grant GM_xmlHttpRequest // @grant GM.download // @match *://*.gayporntube.com/video/* // @webRequest {"selector":"*fluidplayer*","action":"cancel"} // ==/UserScript== (async function() { const max_retries = 3; const timeOut = 2000; console.log("GBTPP: Script started."); const videoplayer = document.getElementById('play-video'); if (!videoplayer) { console.error("GBTPP: No #play-video element found"); return; } console.log("GBTPP: Found #play-video element."); const videoplayerSource = videoplayer.querySelector('source'); if (!videoplayerSource) { console.error("GBTPP: No <source> inside #play-video"); return; } console.log("GBTPP: Found video source element."); const pattern = /\/\?br=\d*$/; const src = videoplayerSource.src.replace(pattern, ''); if (src !== videoplayerSource.src) { videoplayerSource.src = src; console.log("GBTPP: Cleaned video source URL."); } videoplayer.removeAttribute("height"); videoplayer.removeAttribute("width"); videoplayer.setAttribute("preload", "auto"); videoplayer.focus(); console.log("GBTPP: Configured native video player."); let retries = 0; await downloadVideo(videoplayerSource.src); async function downloadVideo(url) { try { // UI feedback area const statusBox = document.createElement("div"); statusBox.classList.add("blue"); statusBox.style.fontWeight = "bold"; statusBox.textContent = "Starting preload…"; videoplayer.parentNode.insertBefore(statusBox, videoplayer.nextSibling); console.log("GBTPP: UI status box created."); console.log("GBTPP: Initiating full preload."); const response = await new Promise((resolve, reject) => { GM.xmlHttpRequest({ method: 'GET', responseType: 'blob', url: url, headers: { "Content-Type": "video/mp4", "Accept": "video/mp4" }, onprogress: (event) => { if (event.lengthComputable) { const loadedMB = (event.loaded / 1048576).toFixed(2); const totalMB = (event.total / 1048576).toFixed(2); const percent = (event.loaded / event.total * 100).toFixed(1); statusBox.textContent = `Preloaded ${loadedMB} / ${totalMB} MB (${percent}%)`; console.log(`GBTPP: Download progress: ${loadedMB}/${totalMB} MB (${percent}%)`); } else { statusBox.textContent = `Preloaded ${(event.loaded / 1048576).toFixed(2)} MB…`; console.log(`GBTPP: Download progress: ${(event.loaded / 1048576).toFixed(2)} MB loaded.`); } }, onload: resolve, onerror: reject, ontimeout: reject }); }); console.log("GBTPP: Full preload completed."); console.log("GBTPP: Creating blob from response."); const blob = new Blob([response.response], { type: 'video/mp4' }); const objectUrl = URL.createObjectURL(blob); console.log("GBTPP: Blob created and Object URL obtained."); // keep playback position/state console.log("GBTPP: Updating video player source with new blob URL."); const { currentTime, paused, ended } = videoplayer; videoplayerSource.src = objectUrl; videoplayer.load(); videoplayer.currentTime = currentTime; if (!paused && !ended && currentTime > 0) { videoplayer.play(); } console.log("GBTPP: Video player source updated and playback state restored."); // notify user final statusBox.textContent = "Video fully preloaded (Click Download button to save video)"; console.log("GBTPP: Final user notification displayed."); const container = document.querySelector("#tab_video_info"); if (container) { const dlBttn = container.querySelector(".bttn"); if (dlBttn) { console.log("GBTPP: Updating Download button."); try { const href = dlBttn.getAttribute('href'); const urlObj = new URL(href, location.href); const filename = urlObj.searchParams.get('download_filename') || "video.mp4"; dlBttn.href = objectUrl; dlBttn.download = filename; console.log(`GBTPP: Download button updated with filename: ${filename}`); } catch (e) { console.warn("GBTPP: Could not parse filename, but download button should still work.", e); } } } } catch (err) { console.error("GBTPP: An error occurred during preload.", err); if (retries++ < max_retries) { console.warn(`GBTPP: Retry ${retries}/${max_retries} after error`, err); setTimeout(() => downloadVideo(url), timeOut); } else { console.error(`GBTPP: Failed after ${max_retries} retries. Giving up.`, err); alert("GBTPP: Video preload failed after multiple attempts."); } } } })();