html画中画播放器,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)

}

})();

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值