// ==UserScript== // @name B站和油管html视频截图 // @namespace Violentmonkey Scripts // @match https://www.youtube.com/* // @match https://www.bilibili.com/video/* // @match https://www.bilibili.com/bangumi/play/* // @match https://www.bilibili.com/list/watchlater* // @grant none // @version 1.1 // @author weixia // @description 2024/7/21 20:52:22 // @downloadURL https://update.greasyfork.icu/scripts/501383/B%E7%AB%99%E5%92%8C%E6%B2%B9%E7%AE%A1html%E8%A7%86%E9%A2%91%E6%88%AA%E5%9B%BE.user.js // @updateURL https://update.greasyfork.icu/scripts/501383/B%E7%AB%99%E5%92%8C%E6%B2%B9%E7%AE%A1html%E8%A7%86%E9%A2%91%E6%88%AA%E5%9B%BE.meta.js // ==/UserScript== (function () { function localElement() { let domain = window.location.host; if (domain === 'www.youtube.com') { return { host: 'youtube', video: document.querySelector('#container .html5-video-container video'), control: document.querySelector('#container .ytp-right-controls') }; } else if (domain === 'www.bilibili.com') { return { host: 'bilibili', video: document.querySelector('#bilibili-player .bpx-player-video-wrap video'), control: document.querySelector('#bilibili-player .bpx-player-control-bottom-right') }; } } // 复制当前帧到剪贴板 function captureImage(video) { let canvas = document.createElement('canvas'); // 设置画布与当前帧宽高一致 canvas.width = video.videoWidth; canvas.height = video.videoHeight; canvas.getContext('2d').drawImage(video, 0, 0); // 返回base64编码url //let baseUrl = canvas.toDataURL('image/png'); // 转为Blob对象,写入剪贴板 canvas.toBlob(async (blob) => { let data = new ClipboardItem({ "image/png": blob }); await navigator.clipboard.write([data]); }, 'image/png'); canvas.remove(); } // 截图流程:播放状态先暂停再截图和继续播放 function capture(video) { if (!video.paused) { video.pause(); captureImage(video); video.play(); } else { captureImage(video); } } // 创建Trusted Types API策略,解决youtube无法注入问题 let policy; if (window.trustedTypes && window.trustedTypes.createPolicy) { policy = window.trustedTypes.createPolicy('user-script', { createHTML: (string, sink) => string }); } // 创建截图按钮 let button; let content; if (localElement().host === 'youtube') { button = document.createElement('button'); content = ``; button.classList.add('ytp-button'); } else if (localElement().host === 'bilibili') { button = document.createElement('div'); content = `
截屏
`; } button.innerHTML = policy.createHTML(content) || content; // 点击事件监听 button.addEventListener('click', function () { let video = localElement().video; capture(video); }); // 按键P进行截图 document.querySelector('body').addEventListener('keydown', function(event) { if (event.key === 'P') { let video = localElement().video; capture(video); } }); // 若播放器控制条出现,添加截图按钮,并取消元素监听 observer = new MutationObserver((mutationList, observer) => { let = control = localElement().control; if (control && control.childElementCount > 0) { control.insertBefore(button, control.firstChild); observer.disconnect(); } }); observer.observe(document.querySelector('body'), { childList: true, // 观察目标子节点的变化,是否有添加或者删除 attributes: true, // 观察属性变动 subtree: true, // 观察后代节点,默认为 false }); })();