您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Prevents HTML5 videos from auto-playing in new tabs on any page (not just YouTube) and pauses videos when leave tab. From Dan Moorehead (xeonx1), developer of PowerAccess™ (http://PowerAccessDB.com) (https://twitter.com/PowerAccessDB).
当前为
// ==UserScript== // @name Disable HTML5 Video AutoPlay and Background Play (Pause On Leave Tab) // @namespace xeonx1 // @version 1.4 // @description Prevents HTML5 videos from auto-playing in new tabs on any page (not just YouTube) and pauses videos when leave tab. From Dan Moorehead (xeonx1), developer of PowerAccess™ (http://PowerAccessDB.com) (https://twitter.com/PowerAccessDB). // @author Dan Moorehead (xeonx1), developer of PowerAccess™ (http://PowerAccessDB.com) (https://twitter.com/PowerAccessDB) // @match http://*/* // @match https://*/* // @grant none // ==/UserScript== (function () { 'use strict'; // **** User Preferences **** //whether to pause videos when leaving a tab they are playing on var pauseOnLeaveTab = true; // Number of milliseconds after clicking where a video is allowed to autoplay. var allowAutoPlayWithinMillisecondsOfClick = 500; //you can add domains (with or without subdomain, must not include http://, etc.) to always allow auto-play //pause on leave tab will still function however var autoPlayDomains = [ /*"youtube.com"*/ ]; var hasAutoPlayDomains = autoPlayDomains.length > 0; // **** End Preferences *** /* Beyond this point is the logic of the script. Do not edit unless you know what you are doing. */ var lastClickTimeMs = 0; //determine name of event for switched away from tab, based on the browser var tabHiddenPropertyName, tabVisibleChangedEventName; if ("undefined" !== typeof document.hidden) { tabHiddenPropertyName = "hidden"; tabVisibleChangedEventName = "visibilitychange"; } else if ("undefined" !== typeof document.webkitHidden) { tabHiddenPropertyName = "webkitHidden"; tabVisibleChangedEventName = "webkitvisibilitychange"; } else if ("undefined" !== typeof document.msHidden) { tabHiddenPropertyName = "msHidden"; tabVisibleChangedEventName = "msvisibilitychange"; } function safeAddHandler(element, event, handler) { element.removeEventListener(event, handler); element.addEventListener(event, handler); } function getVideos() { //OR: Can also add audio elements return document.getElementsByTagName("video"); } function isPlaying(vid) { return !!(vid.currentTime > 0 && !vid.paused && !vid.ended && vid.readyState > 2); } function onTabVisibleChanged() { //console.log("Tab visibility changed for Video auto-player disabling user script. Document is hidden status: ", document[tabHiddenPropertyName]); var videos = getVideos(); //if doc is hidden (switched away from that tab), then pause all its videos if (document[tabHiddenPropertyName]) { //remember had done this document.wasPausedOnChangeTab = true; //pause all videos, since for (var i = 0; i < videos.length; i++) { var vid = videos[i]; if (vid.isPlaying) { vid.wasPausedOnChangeTab = true; console.log("Paused video playback because switched away from this tab for video with source: ", vid.currentSrc); } //always pause just in case isPlaying isn't always reliable vid.pause(); } } //document is now the active tab else { document.wasPausedOnChangeTab = false; //reset state (unless need to use this field or delay this) //TODO-MAYBE: if want to auto-play once switch back to a tab if had paused before, then uncomment below, after changing from forEach() to for loop // getVideos().forEach( function(vid) { // if (vid.wasPausedOnChangeTab == true) { // vid.wasPausedOnChangeTab = false; // vid.play(); // } // } ); } } //handle active tab change events for this document/tab if (pauseOnLeaveTab) { safeAddHandler(document, tabVisibleChangedEventName, onTabVisibleChanged); } //returns true if auto-play is always allowed, whitelisted, so should do nothing to it function isAutoPlayAllowedDomain(s) { // Check if video src is whitelisted. if (hasAutoPlayDomains) { for (var i = 0; i < autoPlayDomains.length; i++) { var reg = new RegExp("https?\:\/\/[a-zA-Z0-9\.\-]*?\.?" + autoPlayDomains[i].replace(/\./, "\.") + "\/", "i"); if (s.match(reg) !== null) { return true; } } } return false; } //on pause or ended/finished, change playing state back to not-playing, so know to start preventing playback again unless after a click function onPaused(e) { e.target.isPlaying = false; } function onPlay(e) { // React when a video begins playing var msSinceLastClick = Date.now() - lastClickTimeMs; var vid = e.target; //exit, do nothing if is already playing (but not if undefined/unknown), in case clicked on seekbar, volume, etc. - don't toggle to paused state on each click if(vid.isPlaying == true) { return; } vid.isPlaying = true; //if haven't clicked recently on video, consider it auto-started, so prevent playback by pausing it (unless whitelisted source domain to always play from) if (msSinceLastClick > allowAutoPlayWithinMillisecondsOfClick && !isAutoPlayAllowedDomain(vid.currentSrc)) { vid.pause(); //remember video is no longer playing - just in case, though event handler for pause should also set this vid.isPlaying = false; console.log("Paused video from source: ", vid.currentSrc); } } function addListenersToVideo(vid) { if (vid.hasAutoPlayHandlers != true) { vid.hasAutoPlayHandlers = true; safeAddHandler(vid, "play", onPlay); //NOTE: Seems playing is needed in addition to play event, but isn't this just supposed to occur whenever play, plus after play once buffering is finished? safeAddHandler(vid, "playing", onPlay); safeAddHandler(vid, "pause", onPaused); safeAddHandler(vid, "ended", onPaused); } } function addListeners() { var videos = getVideos(); //OR: Can get audio elements too for (var i = 0; i < videos.length; i++) { // Due to the way some sites dynamically add videos, the "playing" event is not always sufficient. // Also, in order to handle dynamically added videos, this function may be called on the same elements. // Must remove any existing instances of this event listener before adding. Prevent duplicate listeners. var vid = videos[i]; addListenersToVideo(vid); } } //handle click event so can limit auto play until X time after a click safeAddHandler(document, "click", function () { lastClickTimeMs = Date.now(); }); var observer = new MutationObserver(function(mutations) { // Listen for elements being added. Add event listeners when video elements are added. mutations.forEach(function(mutation) { if (mutation.type == "attributes" && mutation.target.tagName == "VIDEO") { //&& mutation.attributeName == "src" videoAdded = true; addListenersToVideo(mutation.target); } if (mutation.addedNodes.length > 0) { addListeners(); //faster to use getElementsByTagName() for rarely added types vs. iterating over all added elements, checking tagName // for (var i = 0; i < mutation.addedNodes.length; i++) { // var added = mutation.addedNodes[i]; // if (added.nodeType == 1 && added.tagName == "VIDEO") { // videoAdded = true; // } // } } }); }); //subscribe to documents events for node added and src attribute changed via MutatorObserver, limiting to only src attribute changes observer.observe(document, { attributes: true, childList: true, subtree: true, characterData: false, attributeFilter: ['src'] }); //don't also need to handle "spfdone" event //hookup event handlers for all videos that exist now (will still add to any that are inserted later) addListeners(); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址