您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
2020/10/10 下午3:21:48
/*! * test * (c) 2020 lincong1987 */ // ==UserScript== // @name 所有网站启用画中画 OPEN PIP IN ALL SITE // @namespace Violentmonkey Scripts // @match <all_urls> // @grant none // @version 1.3 // @author lincong1987 // @description 2020/10/10 下午3:21:48 // @require https://unpkg.com/[email protected]/dist/jquery.js // @require https://unpkg.com/[email protected]/dist/vue.js // ==/UserScript== (function ($) { var appendToolbar = function ($video) { var width = $video.width() var position = $video.css('position') var parent_position = $video.parent().css('position') var parent_display = $video.parent().css('display') var $toolbar = $(` <div class='us_pip_toolbar'> <button type='button' class="us_pip_toolbar__button" title='点击打开画中画'>PIP画中画</button> </div> `).data('video', $video) $video.after($toolbar) if (position === 'absolute' || position === 'fixed' || parent_position === 'relative' || parent_display === 'flex') { $toolbar.addClass('us_pip_toolbar__absolute') } else { $toolbar.width(width).addClass('us_pip_toolbar__static') } $toolbar.on('click', 'button', function () { $video.get(0).requestPictureInPicture() }) } var doFuck = function () { var $videos = $('video') $videos.each(function () { var $this = $(this) var isFucked = $this.data('isFucked') if (isFucked === true) { return } else { $this.data('isFucked', true) appendToolbar($this) } }) setTimeout(function () { doFuck() }, 5 * 1000) } doFuck() $('head').append(`<style> .us_pip_toolbar { box-sizing: border-box; } .us_pip_toolbar__absolute { position: absolute; top: -28px; left: 0; z-index: 99999999; } .us_pip_toolbar__static { border: 1px solid #ccc; background: #dadada; padding: 4px; font-size: 0; } .us_pip_toolbar .us_pip_toolbar__button { display: inline-block; padding: 0px 5px; font-size: 12px; line-height: 28px; height: 28px; text-align: center; cursor: pointer; background: none; border: 1px solid; border-radius: 3px; color: #fff; background-color: #0084ff; border-color: #0084ff; font-family: sans-serif; font-weight: bold; opacity: 0.8; } .us_pip_toolbar .us_pip_toolbar__button:hover { translate: all 0.8s; opacity: 1; } .body_us_pip_toolbar { position: fixed; bottom: 10px; left: 10px; z-index: 99999999; max-height: 500px; overflow: auto; } .body_us_pip_toolbar .body_us_pip_item { height: 72px; width: 128px; background-size: cover; margin-bottom: 8px; position: relative; } .body_us_pip_toolbar .body_us_pip_item .us_pip_toolbar__button__open { height: 72px; width: 128px; background: center center no-repeat url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB0PSIxNjAyMzM2MTIwNzczIiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjM1NDUiIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPjxkZWZzPjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+PC9zdHlsZT48L2RlZnM+PHBhdGggZD0iTTUxMiAwQzIyOS4yNzYwOTggMCAwIDIyOS4yNzYwOTggMCA1MTJTMjI5LjI3NjA5OCAxMDI0IDUxMiAxMDI0czUxMi0yMjkuMjc2MDk4IDUxMi01MTJTNzk0LjcyMzkwMiAwIDUxMiAweiBtMjAxLjcwMzAyNCA1MzYuNTc2TDQzMy4zNzY3OCA3NjAuODU2OTc2Yy01LjY5NDQzOSA0LjU5NTUxMi0xMi42ODc2MSA2Ljg5MzI2OC0xOS42ODA3OCA2Ljg5MzI2OC00LjU5NTUxMiAwLTkuMjkwOTI3LTAuOTk5MDI0LTEzLjY4NjYzNC0zLjA5Njk3NkMzODkuMTIgNzU5LjM1ODQzOSAzODIuMTI2ODI5IDc0OC4zNjkxNzEgMzgyLjEyNjgyOSA3MzYuMjgwOTc2VjI4Ny44MTg5MjdjMC0xMi4wODgxOTUgNi45OTMxNzEtMjMuMTc3MzY2IDE3Ljg4MjUzNy0yOC4zNzIyOTMgMTAuODg5MzY2LTUuMjk0ODI5IDIzLjg3NjY4My0zLjc5NjI5MyAzMy4zNjc0MTQgMy43OTYyOTNsMjgwLjIyNjM0MiAyMjQuMTgxMDczYzcuNDkyNjgzIDUuOTk0MTQ2IDExLjc4ODQ4OCAxNS4wODUyNjggMTEuNzg4NDg4IDI0LjU3NiAwLjA5OTkwMiA5LjU5MDYzNC00LjE5NTkwMiAxOC42ODE3NTYtMTEuNjg4NTg2IDI0LjU3NnoiIHAtaWQ9IjM1NDYiIGZpbGw9IiNlZWVlZWUiIGRhdGEtc3BtLWFuY2hvci1pZD0iYTMxM3guNzc4MTA2OS4wLmkxNCIgY2xhc3M9InNlbGVjdGVkIj48L3BhdGg+PC9zdmc+'); color: #fff; position: absolute; text-indent: -999999em; overflow: hidden; border: none 0; cursor: pointer; } .body_us_pip_toolbar .body_us_pip_item .us_pip_toolbar__button__open:hover { background: center center no-repeat url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB0PSIxNjAyMzM2MTIwNzczIiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjM1NDUiIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPjxkZWZzPjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+PC9zdHlsZT48L2RlZnM+PHBhdGggZD0iTTUxMiAwQzIyOS4yNzYwOTggMCAwIDIyOS4yNzYwOTggMCA1MTJTMjI5LjI3NjA5OCAxMDI0IDUxMiAxMDI0czUxMi0yMjkuMjc2MDk4IDUxMi01MTJTNzk0LjcyMzkwMiAwIDUxMiAweiBtMjAxLjcwMzAyNCA1MzYuNTc2TDQzMy4zNzY3OCA3NjAuODU2OTc2Yy01LjY5NDQzOSA0LjU5NTUxMi0xMi42ODc2MSA2Ljg5MzI2OC0xOS42ODA3OCA2Ljg5MzI2OC00LjU5NTUxMiAwLTkuMjkwOTI3LTAuOTk5MDI0LTEzLjY4NjYzNC0zLjA5Njk3NkMzODkuMTIgNzU5LjM1ODQzOSAzODIuMTI2ODI5IDc0OC4zNjkxNzEgMzgyLjEyNjgyOSA3MzYuMjgwOTc2VjI4Ny44MTg5MjdjMC0xMi4wODgxOTUgNi45OTMxNzEtMjMuMTc3MzY2IDE3Ljg4MjUzNy0yOC4zNzIyOTMgMTAuODg5MzY2LTUuMjk0ODI5IDIzLjg3NjY4My0zLjc5NjI5MyAzMy4zNjc0MTQgMy43OTYyOTNsMjgwLjIyNjM0MiAyMjQuMTgxMDczYzcuNDkyNjgzIDUuOTk0MTQ2IDExLjc4ODQ4OCAxNS4wODUyNjggMTEuNzg4NDg4IDI0LjU3NiAwLjA5OTkwMiA5LjU5MDYzNC00LjE5NTkwMiAxOC42ODE3NTYtMTEuNjg4NTg2IDI0LjU3NnoiIHAtaWQ9IjM1NDYiIGZpbGw9IiNlYjczNTAiIGRhdGEtc3BtLWFuY2hvci1pZD0iYTMxM3guNzc4MTA2OS4wLmkxNCIgY2xhc3M9InNlbGVjdGVkIj48L3BhdGg+PC9zdmc+'); } .body_us_pip_toolbar .body_us_pip_item .us_pip_toolbar__button__open:before { } <style>`) var $bodyToolbar = $(` <div class='body_us_pip_toolbar' id='body_us_pip_toolbar'> </div> `) var init = function () { $('body').append($bodyToolbar) new Vue({ el: '#body_us_pip_toolbar', template: ` <div class='body_us_pip_toolbar' id='body_us_pip_toolbar'> <div v-for='(item, i) in list' class='body_us_pip_item' :style="getStyle(item)"> <button type='button' class="us_pip_toolbar__button__open" @click='open($event, item, i)' title='画中画播放'> </button> </div> </div> `, data () { return { list: [], } }, methods: { capture (video) { var eventTester = function(e){ video.addEventListener(e,function(){ console.log((new Date()).getTime(),e) },false); } // eventTester("loadstart"); //客户端开始请求数据 // eventTester("progress"); //客户端正在请求数据 // eventTester("suspend"); //延迟下载 // eventTester("abort"); //客户端主动终止下载(不是因为错误引起) // eventTester("loadstart"); //客户端开始请求数据 // eventTester("progress"); //客户端正在请求数据 // eventTester("suspend"); //延迟下载 // eventTester("abort"); //客户端主动终止下载(不是因为错误引起), // eventTester("error"); //请求数据时遇到错误 // eventTester("stalled"); //网速失速 // eventTester("play"); //play()和autoplay开始播放时触发 // eventTester("pause"); //pause()触发 // eventTester("loadedmetadata"); //成功获取资源长度 // eventTester("loadeddata"); // // eventTester("waiting"); //等待数据,并非错误 // eventTester("playing"); //开始回放 // eventTester("canplay"); //可以播放,但中途可能因为加载而暂停 // eventTester("canplaythrough"); //可以播放,歌曲全部加载完毕 // eventTester("seeking"); //寻找中 // eventTester("seeked"); //寻找完毕 // eventTester("timeupdate"); //播放时间改变 // eventTester("ended"); //播放结束 // eventTester("ratechange"); //播放速率改变 // eventTester("durationchange"); //资源长度改变 // eventTester("volumechange"); //音量改变 // return new Promise((resolve, reject) => { var canvas = document.createElement('canvas') video.crossorigin='anonymous' //setTimeout(()=>{ // video.addEventListener('canplay', (e) => { canvas.width = video.videoWidth * 0.25 canvas.height = video.videoHeight * 0.25 canvas.getContext('2d'). drawImage(video, 0, 0, canvas.width, canvas.height) var src = '' try { src = canvas.toDataURL('image/png'); //resolve(src) } catch (e) { console.log(e) // reject('') } return src // }) //}, 1000) // }) }, collect () { var me = this clearTimeout(this.$timer) var $videos = $('video') $videos.each(function () { var $this = $(this) var vedio = $this.get(0) var fuckedId = $this.data('fuckedId') if (!fuckedId) { if (vedio.paused === false) { fuckedId = new Date().getTime() $this.data('fuckedId', fuckedId).attr('fuckfuckfuck', fuckedId) me.list.push({ fuckedId: fuckedId, //src: me.capture(vedio) }) } } }) this.$timer = setTimeout(() => { this.collect() }, 5 * 1000) }, open (e, item, i) { var videos = document.getElementsByTagName('video') for (var i = 0; i <= videos.length - 1; i++) { if ($(videos[i]).data('fuckedId') === item.fuckedId) { try {videos[i].requestPictureInPicture()} catch (e) {} break } } }, remove (e, item, i) {}, getHeight () { }, getStyle (item) { var style = {} var src = this.capture( $('video[fuckfuckfuck=\'' + item.fuckedId + '\']').get(0)) this.$nextTick(() => { item.src = src }) if (src === '') { style.backgroundColor = 'blue' } else { style.backgroundImage = `url(${src})` } return style }, }, mounted () { this.$timer = 0 this.collect() $('body').on('scroll', () => { this.collect() }) }, }) } setTimeout(function () { init() }, 1000) })($.noConflict(true))