您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Prevents HTML5 videos from auto-playing in new tabs on any page (not just YouTube) and pauses videos when leave tab. NOTE: On YouTube, click the main video area to play the video so don't have to click the Pause/Play button twice for the first time. 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.5
- // @description Prevents HTML5 videos from auto-playing in new tabs on any page (not just YouTube) and pauses videos when leave tab. NOTE: On YouTube, click the main video area to play the video so don't have to click the Pause/Play button twice for the first time. 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) and
- // @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();
- })();