您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Auto-enables PiP for playing videos in Chromium browsers on tab switch. Requires an initial click to unlock and exits on return.
当前为
- // ==UserScript==
- // @name Auto Picture-in-Picture on Tab Change
- // @namespace https://github.com/EzioTheGoat/EzioUserscripts
- // @version 1.3.1
- // @description Auto-enables PiP for playing videos in Chromium browsers on tab switch. Requires an initial click to unlock and exits on return.
- // @author Ezio Auditore
- // @license MIT
- // @icon https://img.icons8.com/ios-filled/64/000000/picture-in-picture.png
- // @match *://*/*
- // @grant none
- // ==/UserScript==
- (function () {
- "use strict";
- /**
- * Auto PiP for Chromium browsers on tab change.
- *
- * The script waits for an initial user click to "unlock" the auto-PiP feature,
- * satisfying the user gesture requirement enforced by browsers. When the page loses focus,
- * if there is an actively playing video, the script requests Picture-in-Picture mode.
- * On regaining focus, it exits Picture-in-Picture mode.
- *
- * Note: PiP mode will not be activated if the video is paused.
- */
- // Flag to indicate that auto-PiP has been unlocked by a user gesture
- let unlocked = false;
- /**
- * Unlocks auto-PiP after the first user click.
- */
- function unlockPiP() {
- unlocked = true;
- document.removeEventListener("click", unlockPiP);
- console.log("Auto-PiP unlocked by user interaction.");
- }
- document.addEventListener("click", unlockPiP);
- /**
- * Returns the first available video element that is actively playing.
- * @returns {HTMLVideoElement|null} The active video element or null if none found.
- */
- function getActiveVideo() {
- const videos = document.querySelectorAll("video");
- for (const video of videos) {
- if (!video.paused && !video.ended) {
- return video;
- }
- }
- return videos.length ? videos[0] : null;
- }
- /**
- * Enters Picture-in-Picture mode if an active (playing) video is found.
- */
- async function enterPiP() {
- if (!unlocked) {
- console.log(
- "Auto-PiP is locked. Please click anywhere on the page to enable it."
- );
- return;
- }
- try {
- const video = getActiveVideo();
- // Only enter PiP if a video exists and it is playing
- if (
- video &&
- !video.paused &&
- document.pictureInPictureElement !== video
- ) {
- await video.requestPictureInPicture();
- console.log("Entered Picture-in-Picture mode.");
- } else {
- console.log("No active (playing) video available for PiP.");
- }
- } catch (error) {
- console.error("Error entering Picture-in-Picture mode:", error);
- }
- }
- /**
- * Exits Picture-in-Picture mode if active.
- */
- async function exitPiP() {
- try {
- if (document.pictureInPictureElement) {
- await document.exitPictureInPicture();
- console.log("Exited Picture-in-Picture mode.");
- }
- } catch (error) {
- console.error("Error exiting Picture-in-Picture mode:", error);
- }
- }
- /**
- * Helper function to delay the execution of an action.
- * @param {Function} action - The action to perform after the delay.
- * @param {number} delay - The delay in milliseconds.
- */
- function delayedAction(action, delay = 100) {
- setTimeout(action, delay);
- }
- // Event listeners for tab focus and blur events to trigger PiP mode changes.
- window.addEventListener("blur", () => {
- delayedAction(enterPiP);
- });
- window.addEventListener("focus", () => {
- delayedAction(exitPiP);
- });
- // Additional visibility change handling for more robust behavior.
- document.addEventListener("visibilitychange", () => {
- if (document.visibilityState === "hidden") {
- delayedAction(enterPiP);
- } else if (document.visibilityState === "visible") {
- delayedAction(exitPiP);
- }
- });
- })();