您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
除youtube以外按c加速,按x减速,按z复位,youtube按v加速。点击右上角油猴按钮可开关视频速度记忆功能。
当前为
// ==UserScript== // @name 视频倍速工具 // @namespace http://tampermonkey.net/ // @version 0.2.8 // @description 除youtube以外按c加速,按x减速,按z复位,youtube按v加速。点击右上角油猴按钮可开关视频速度记忆功能。 // @author call duck // @match *://*/* // @icon https://www.google.com/s2/favicons?sz=64&domain=bilibili.com // @grant GM_registerMenuCommand // @grant GM_unregisterMenuCommand // @grant GM_setValue // @grant GM_getValue // @grant GM_addValueChangeListener // @run-at document-end // @license MIT // ==/UserScript== // 使用方法:除youtube以外按c加速,按x减速,按z复位,youtube按v加速。 (function () { "use strict"; if (window.innerWidth < 100) { return; } console.log(document.getElementsByTagName('video')) const REMEMBER_KEY = `${location.hostname}_da4e1a5f0c5b46cdadadf70af3c19f37`; let isRememberSpeed = GM_getValue(REMEMBER_KEY, false); const SPEED_KEY = "2779054e81654c2990dd9d2bfe9202aa"; const originSpeed = localStorage.getItem(SPEED_KEY); let speed; if (isNaN(originSpeed) || !originSpeed) { speed = 1; localStorage.setItem(SPEED_KEY, 1); } else if (isRememberSpeed) { speed = originSpeed; } else { speed = 1; } speed = parseFloat(parseFloat(speed).toFixed(2)); let videos; const step = 0.05; let menuId; function addRememberMenu() { if (!isRememberSpeed) { addOpenRememberMenu(); } else { addCloseRememberMenu(); } GM_addValueChangeListener( REMEMBER_KEY, function name(key, oldValue, newValue) { GM_unregisterMenuCommand(menuId); if (newValue === true) { addCloseRememberMenu(); } else { addOpenRememberMenu(); } } ); } addRememberMenu(); async function addOpenRememberMenu() { if (menuId) GM_unregisterMenuCommand(menuId); menuId = await GM.registerMenuCommand("打开视频速度记忆功能", async () => { GM_setValue(REMEMBER_KEY, true); videos.forEach((v)=>{ notify(v,"视频播放速度记忆功能已打开"); }) }); } async function addCloseRememberMenu() { if (menuId) GM_unregisterMenuCommand(menuId); menuId = await GM.registerMenuCommand("关闭视频速度记忆功能", async () => { GM_setValue(REMEMBER_KEY, false); videos.forEach((v)=>{ notify(v,"视频播放速度记忆功能已关闭"); }) }); } videos = Array.prototype.slice.call(document.getElementsByTagName("video")); new Promise((res) => { if (!videos) { let count = 0; const maxCount = 3; function _getVideo() { setTimeout(() => { videos = getVideo(); count++; if (!videos && count < maxCount) { _getVideo(); } else { res(videos); } }, 1000); } _getVideo(); } else { res(videos); } }).then((v) => { videos = v; syncSpeedToVideo(); }); function getVideos() { let v; const videoElements = Array.prototype.slice.call(document.getElementsByTagName("video")); if (window.location.hostname === "www.bilibili.com") { const bPlayerCollection = document.getElementsByTagName("bwp-video"); if (bPlayerCollection.length > 0) { videoElements.push(bPlayerCollection[0]); } } if ( location.hostname === "www.reddit.com" && window.location.pathname.match(/\/r\/\S+\/comments\/.+/) ) { const player = document.getElementsByTagName("shreddit-player"); if (player.length > 0) { v = player[0].shadowRoot.querySelector("video"); videoElements.push(v) } } /* if (location.hostname === "www.youtube.com") { if (v && v.className.indexOf("video-stream") === -1) { notify('视频正在初始化,请稍候') return null } } */ return videoElements; } function formatSpeed(s) { s = parseFloat(s.toFixed(2)); if (s > 10) { return 10; } if (s <= 0.1) { return 0.1; } return s; } window.addEventListener("keypress", function (e) { console.log(document.getElementsByTagName('video')) const activeElement = this.document.activeElement; if ( activeElement.tagName.toLowerCase() === "input" || activeElement.contentEditable === true || activeElement.tagName.toLowerCase() === "textarea" ) { return; } const keyList = ['z','x','c','v'] const key = e.key.toLowerCase() if (keyList.indexOf(key)===-1) { return } // 获取video元素 videos = getVideos(); if (videos.length===0) { return; } // ** if (e.key.toLowerCase() === "c") { if (this.location.hostname === "www.youtube.com") { return; } speed = speed + step; changeSpeed(videos, formatSpeed(speed)); } // youtube单独处理。 if ( this.location.hostname === "www.youtube.com" && e.key.toLowerCase() === "v" ) { speed = speed + step; changeSpeed(videos, formatSpeed(speed)); } if (e.key.toLowerCase() === "x") { speed = speed - step; changeSpeed(videos, formatSpeed(speed)); } if (e.key.toLowerCase() === "z") { speed = 1; changeSpeed(videos, formatSpeed(speed)); } }); window.onload = function () { const videoElements = document.getElementsByTagName("video"); if (videoElements.length === 0) return; videos = videoElements[0]; }; function changeSpeed(videos, speed) { videos.forEach((video)=>{ video.playbackRate = speed; localStorage.setItem(SPEED_KEY, speed); video.removeEventListener("playing", syncSpeedToVideo); video.removeEventListener("play", syncSpeedToVideo); video.addEventListener("playing", syncSpeedToVideo); video.addEventListener("play", syncSpeedToVideo); notify(video,video.playbackRate); }) } function syncSpeedToVideo() { videos.forEach((video)=>{ setTimeout(() => { video.playbackRate = formatSpeed(speed); }, 1); }) } /* function handleVideo(video) { if (isRememberSpeed) { video.playbackRate = speed; } else { speed = video.playbackRate; } addRememberMenu(); video.addEventListener("ratechange", function () { speed = video.playbackRate; }); } */ function notify(video,msg) { const className = "edbe85b469d47a8833b84e259864e33"; const box = document.createElement("div"); box.className = className; box.style.background = "#333"; box.style.color = "#fff"; box.style.padding = "8px 20px"; box.style.position = "fixed"; box.style.margin = "auto"; box.style.left = "50%"; box.style.top = "60px"; box.style.transform = "translateX(-50%)"; box.style.borderRadius = "5px"; box.style.zIndex = "10000"; box.style.fontSize = "16px"; box.innerHTML = msg; const oldBox = document.querySelectorAll("." + className); if (oldBox.length) { oldBox.forEach((b) => { b.remove(); }); } if (video && document.fullscreenElement) { video.parentElement.appendChild(box); } else { document.body.appendChild(box); } setTimeout(() => { box.remove(); }, 2000); } })();