您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
向兼容浏览器中的HTML5视频添加画中画按钮
- // ==UserScript==
- // @name Picture In Picture
- // @name:zh-CN HTML5画中画
- // @namespace http://github.com/eternal-flame-AD/picture-in-picture/
- // @version 0.2
- // @homepage http://github.com/eternal-flame-AD/picture-in-picture/
- // @description Provide picture in picture functionality to HTML5 videos on supported browsers
- // @description:zh-CN 向兼容浏览器中的HTML5视频添加画中画按钮
- // @compatible chrome 70+
- // @author eternal-flame-AD
- // @include *
- // @grant GM_info
- // @license Apache-2.0
- // ==/UserScript==
- (function() {
- 'use strict';
- if (!("pictureInPictureEnabled" in document)) {
- console.log("Your browser does not support picture in picture. Exiting...")
- return
- }
- if (!document.pictureInPictureEnabled) {
- console.log("Picture in picture is disabled. Exiting...")
- return
- }
- window["PIP_URL_BASE"] = "https://cdn.jsdelivr.net/gh/eternal-flame-AD/picture-in-picture/";
- function formatURL(url) {
- return (!/^(https?:)?\/\//.test(url))?(window['PIP_URL_BASE'] + url):url;
- }
- function createStylesheet(url) {
- url = formatURL(url);
- let elt = document.createElement('link');
- elt.rel = 'stylesheet';
- elt.href = url;
- document.documentElement.appendChild(elt);
- };
- const locateVideoElement = function _self(DOM=document.body) {
- let video = DOM.querySelector("video")
- if (video) return video
- let iframes = DOM.querySelectorAll("iframe")
- for (let iframe of iframes) {
- video = _self(iframe.contentDocument.body)
- if (video) return video
- }
- return null
- }
- let loaded = false;
- const load = function(target) {
- if (loaded) return
- loaded = true;
- createStylesheet('style.css');
- class PIP {
- constructor(target) {
- this.target = target || locateVideoElement(document.body);
- this.outside = false
- let holder = document.createElement('div')
- holder.className = 'pip-indicator-holder pip-off'
- let img = document.createElement('img');
- img.className = 'pip-indicator-logo'
- img.src = formatURL("logo.svg")
- holder.appendChild(img)
- document.body.appendChild(holder)
- this.off = this.off.bind(this)
- this.on = this.on.bind(this)
- this.updateTarget = this.updateTarget.bind(this)
- holder.onclick = () => {
- (this.outside?this.off:this.on)().catch(console.error)
- }
- this.elem = holder;
- }
- updateTarget() {
- if (!this.target.isConnected) this.target = locateVideoElement(document.body);
- let _this = this;
- this.target.addEventListener('enterpictureinpicture', function _self() {
- if (!_this.target.isConnected) {
- _this.target.removeEventListener('enterpictureinpicture', _self)
- return
- }
- _this.outside = true
- _this.elem.classList.replace("pip-off","pip-on")
- });
- this.target.addEventListener('leavepictureinpicture', function _self() {
- if (!_this.target.isConnected) {
- _this.target.removeEventListener('leavepictureinpicture', _self)
- return
- }
- _this.outside = false
- _this.elem.classList.replace("pip-on","pip-off")
- });
- }
- async on() {
- this.updateTarget()
- await this.target.requestPictureInPicture()
- }
- async off() {
- await document.exitPictureInPicture()
- }
- }
- //new PIP(target)
- new PIP() // Fixed ad problem
- }
- {
- let observers = []
- let observe = function _self(DOM=document.body, _window=window, debug=false) {
- const gotVideo = function(video) {
- if (video.disablePictureInPicture) return;
- console.log("Got video element! Loading...")
- load(video)
- observers.forEach(obs=>{
- obs.disconnect()
- })
- }
- {
- // Existing video
- let video = locateVideoElement(DOM)
- if (video) gotVideo(video)
- }
- {
- // Existing iframe
- DOM.querySelectorAll("iframe").forEach(iframe=>{
- iframe.contentWindow.onload = function() {
- iframe.contentWindow["PIP_OBSERVING"] = true;
- _self(iframe.contentDocument.body,iframe.contentWindow)
- }
- })
- }
- console.log("No video elements. Watching for changes...")
- let callback = function(mutationList) {
- mutationList.forEach((mutation)=>{
- mutation.addedNodes.forEach((node)=>{
- if (debug) console.log(node)
- const search = function (node,tag) {
- if (node.tagName && node.tagName.toUpperCase()==tag.toUpperCase()) {
- return node
- }
- return node.querySelector && node.querySelector(tag)
- }
- {
- // Dynamically added video
- let video = search(node, "video")
- if (video) gotVideo(video)
- }
- {
- // Dynamically added iframe
- let iframe = search(node, "iframe")
- if (iframe) {
- iframe.contentWindow.onload = function() {
- if (iframe.contentWindow["PIP_OBSERVING"] == true) return;
- iframe.contentWindow["PIP_OBSERVING"] = true;
- _self(iframe.contentDocument.body,iframe.contentWindow)
- }
- }
- }
- })
- })
- }
- let observer = new _window.MutationObserver(callback)
- observer.observe(DOM,{
- childList: true,
- attributes: false,
- subtree: true
- })
- observers.push(observer)
- window.observers = observers;
- }
- observe(document.body)
- }
- })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址