您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Makes <video> more usable across the web by enabling all controls, downloads, picture-in-picture, etc. May cause usability issues on some sites but is generally an improvment.
当前为
// ==UserScript== // @name Universal <video> Fixer // @namespace http://tampermonkey.net/ // @version 0.1.0 // @description Makes <video> more usable across the web by enabling all controls, downloads, picture-in-picture, etc. May cause usability issues on some sites but is generally an improvment. // @author @varenc // @match *://*/* // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABABAMAAABYR2ztAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAANIaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJYTVAgQ29yZSA2LjAuMCI+CiAgIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5zOnRpZmY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vdGlmZi8xLjAvIgogICAgICAgICAgICB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyI+CiAgICAgICAgIDx0aWZmOkNvbXByZXNzaW9uPjE8L3RpZmY6Q29tcHJlc3Npb24+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjcyPC90aWZmOlhSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpZUmVzb2x1dGlvbj43MjwvdGlmZjpZUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6UGhvdG9tZXRyaWNJbnRlcnByZXRhdGlvbj4yPC90aWZmOlBob3RvbWV0cmljSW50ZXJwcmV0YXRpb24+CiAgICAgICAgIDxleGlmOlBpeGVsWERpbWVuc2lvbj4xMDI0PC9leGlmOlBpeGVsWERpbWVuc2lvbj4KICAgICAgICAgPGV4aWY6Q29sb3JTcGFjZT4xPC9leGlmOkNvbG9yU3BhY2U+CiAgICAgICAgIDxleGlmOlBpeGVsWURpbWVuc2lvbj4xMDI0PC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+Ck65VAAAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAYUExURSQkJjQ1NwMDA/Hz7gwMD9DSz6KlpXF0dUWDpyEAAAADdFJOUwT1ipnZE8QAAAKySURBVEjHrZVNj5swEIbTan/ApuuQe9U/UFmGa11NzBkZJ+cIQ84rPvbvd2aMExdnbzuHKIQnL8N8vN7tviBeNDwPrQOgBXxG/GWBPXwMT+MGwIA4Du55XPUfTmFx9mLlJspOKicYqHunxNsWaGv88K8EFM42usgAGKVsKEsoUED3W0ABSlQMLLaBwsohvd0HiZKBmQVK6JIMwbJEqRlgAS/GB1DpE0usgCcBXadpTCxhSmDgwgILlUI5Zx8SywpYtwqoG7ZFL3cJFwG5ClwB9nsAQxKAEuoOBIErHBfnzu90jyXkHWjFTFdH6qFTV3rjCt7uAF6RwLSnBgPWZaKHTHMCyMFi4sstzMnMRStdClDnjud1jsB6Eyv6ABQUPo7aiUq9BSo9PIbRTmMGtKYBbaoAvLWnDJgOHgHsEIUp6wyAWXANJyZUSCIBFKeAgOIt6aZuA5T1JQD4I8boPwfkhbMcN0BVNxGQWI9TO28B8wAUAYcM+H0HmqdAXUWAvhz8nCVZpm8xZ4DSaq0DV2oW29eUoguVDC3tIQP86AUCDd+vL7XNunnC14jdNK2x+TxIGqZ16KY566aEsY3zUp+hz4HWqGh3s6+3I8dL0q0ZFGf0DKlSoKIK+ZobCcd+4jXpEqAVfGXk+fYxuCsJ8HLegVIbHgSD5njGFSUByvORg+fS4nYf3+kZJGD+26wgEfzhA++TwGO7yzFKSEfrbWUQaOwKYPqrROJRvVXiFD2KrGCVWF2OBFooVsBNmh6X2GCpUQDqPjoMu8kttcGBBJZoYk4KlFDpiaBYwFUMoEteUv3o9mhoDQNUkemQnxe9s54BTRXJjwMUQJenA4VL6WRGYKWAjqTvgF7uyKMVU/g1fDo0NTqSdr8EGvCzgHAsosSn8RqO3m8/fsbgv1Hs8bfd18Q/+m3BBdhR+FsAAAAASUVORK5CYII= // @license MIT // @run-at document-idle // @grant none // ==/UserScript== (function() { 'use strict'; function fixVideos() { // Process all videos on the page, making them downloadable and fully functional document.querySelectorAll("video").forEach((video, index) => { console.log(`VideoFixer: Processing <video> #${index + 1}:`, video); video.style.position = "relative"; video.style.zIndex = "999999"; // <-- this is the real trick, forcing the native <video> controls to the front video.controls = true; video.style.pointerEvents = "auto"; const removedAttributes = []; const removedControlsListItems = []; // Remove attributes that restrict functionality ["disablePictureInPicture", "disableRemotePlayback"].forEach((attr) => { if (video.hasAttribute(attr)) { removedAttributes.push(attr); video.removeAttribute(attr); } }); // Remove controlsList restrictions if (video.hasAttribute("controlsList")) { removedControlsListItems.push(...video.getAttribute("controlsList").split(/\s+/)); video.removeAttribute("controlsList"); } if (removedAttributes.length > 0 || removedControlsListItems.length > 0) { console.log(`VideoFixer: Removed restrictions from video #${index + 1}:`, { removedAttributes, removedControlsListItems }); } }); console.log("VideoFixer: All videos processed and fixed!"); } // Set up a MutationObserver to detect new videos being added to the page function setupVideoObserver() { const videoObserver = new MutationObserver((mutations) => { let shouldProcess = false; // Check for new/modified <video> for (const mutation of mutations) { if (mutation.type === 'childList') { const addedVideos = Array.from(mutation.addedNodes).filter(node => node.nodeName === 'VIDEO' || (node.nodeType === Node.ELEMENT_NODE && node.querySelector('video')) ); if (addedVideos.length > 0) { shouldProcess = true; break; } } else if (mutation.type === 'attributes' && mutation.target.nodeName === 'VIDEO') { shouldProcess = true; break; } } if (shouldProcess) { fixVideos(); } }); videoObserver.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['src', 'controlsList', 'disablePictureInPicture', 'disableRemotePlayback'], attributeOldValue: true }); return videoObserver; } function initialize() { console.log("Universal Video Fixer activated!"); fixVideos(); setupVideoObserver(); } // Wait for the DOM to be fully loaded if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', initialize); } else { initialize(); } // Run a check after a short delay to catch videos that load after initial page load, but were missed by the mutation observer setTimeout(fixVideos, 2000); })();