Video Element Rate Controller Re-dux

Add keyboard shortcuts that will increase/decrease the playback rate for video elements.

目前為 2018-08-05 提交的版本,檢視 最新版本

// ==UserScript==
// @name         Video Element Rate Controller Re-dux
// @namespace    https://github.com/mirnhoj/video-element-playbackrate-setter
// @version      1.0
// @description  Add keyboard shortcuts that will increase/decrease the playback rate for video elements.
// @include      http*://*.youtube.com/*
// @include      http*://*.gfycat.com/*
// @include      http*://*.vimeo.com/*
// @include      https://www.facebook.com/video.php*
// @include      https://www.facebook.com/*/videos/*
// @include      https://www.kickstarter.com/*
// @require      https://cdnjs.cloudflare.com/ajax/libs/big.js/5.1.2/big.js
// @grant        none
// ==/UserScript==
/* jshint esversion: 6 */
//
// if you want to extend the functionality of this script to other sites
// besides youtube, add additional @include keys to the metadata block.
//
// if you want to change the default playback rate from 1x, change the line
// "var currentPlaybackRate = 1;" to equal something other than 1, like 1.3 to
// have all videos start playing at an increased speed, or 0.7 to have all
// videos start playing at a decreased speed.
//
// if you want change the granularity of the playback rate adjustment, change
// the line "var speedStep = 0.1;" to equal something other than 0.1, like 0.01
// for more granular adjustments, or 0.25 for less granular adjustments.


var currentPlaybackRate = 1; // default playback rate.
var speedStep = 0.125; // how much to modify speed for each keypress
var displayTimeMilliSec = 1500; // how long to show the current speed indicator in milliseconds
var enhancerExtention = true; // set to false if you aren't using Enhancer for Youtube

var infobox = document.createElement("h1");
infobox.setAttribute("id", "playbackrate-indicator");
infobox.style.position = "absolute";
infobox.style.top = "10%";
infobox.style.right = "10%";
infobox.style.color = "rgba(255, 0, 0, 1)";
infobox.style.zIndex = "99999"; // ensures that it shows above other elements.
infobox.style.visibility = "hidden";
infobox.style.marginTop = "3%";

var timeoutID;
var showDisplay = false;
var pref = "preference-changed";
var eventName = "speed";

if (document.readyState !== "loading") {
    onReady(); // Or setTimeout(onReady, 0); if you want it consistently async
} else {
    document.addEventListener("DOMContentLoaded", onReady);
}

function setPlaybackRate(rate, showInfobox) {
    rate = new Big(rate);
    // grab the video elements and set their playback rate.
    var videoElement = document.getElementsByTagName("video")[0];
    videoElement.playbackRate = rate;
    infobox.innerHTML = rate + "x";
    // add infobox to dom if it doesn't already exist.
    if (videoElement && !document.getElementById("playbackrate-indicator")) {
        videoElement.parentElement.appendChild(infobox);
    }
    // show infobox and update rate indicator.
    if (showInfobox) {
        infobox.style.visibility = "visible";
        // clear out any previous timers and have the infobox hide after the pre-set time period
        window.clearTimeout(timeoutID);
        timeoutID = window.setTimeout(function() {
            infobox.style.visibility = "hidden";
        }, displayTimeMilliSec);
        showDisplay = false;
    }
}

// mimic vlc keyboard shortcuts
function addKeyListener() {
    window.addEventListener('keydown', function(event) {
        var key = event.key;
        var videoElement = document.getElementsByTagName("video")[0];
        currentPlaybackRate = videoElement.playbackRate;
        switch (key) {
            // decrease playback rate if '[' is pressed
            case "[":
                currentPlaybackRate -= speedStep;
                showDisplay = true;
                setPlaybackRate(currentPlaybackRate, showDisplay);
                break;
            // increase playback rate if ']' is pressed
            case "]":
                currentPlaybackRate += speedStep;
                showDisplay = true;
                setPlaybackRate(currentPlaybackRate, showDisplay);
                break;
        }
        if (enhancerExtention === true) {
            window.postMessage({
                enhancerforyoutube: pref,
                name: eventName,
                value: currentPlaybackRate
            }, "*");
        }
    });
}

// show the current speed display on the video when mouse wheel is rolled on the speed element if using Enhancer For Youtube
function addWheelListener() {
    var enhancerToolbar = document.getElementById("enhancer-for-youtube-toolbar");
    var enhancerToolbarChildren = enhancerToolbar.children[0].children;
    for (var i = 0; i < enhancerToolbarChildren.length ; i++ ) {
        if (enhancerToolbarChildren[i].dataset.name === eventName) {
            var speedChild = enhancerToolbarChildren[i];
    }}
    if (speedChild) {
        speedChild.addEventListener('wheel', function(event) {
            var wDelta = event.wheelDelta < 0 ? 'down' : 'up';
            var videoElement = document.getElementsByTagName("video")[0];
            currentPlaybackRate = videoElement.playbackRate;
            switch (wDelta) {
                case "down":
                    // currentPlaybackRate -= speedStep; // uncomment to actually modify the playback speed
                    showDisplay = true;
                    setPlaybackRate(currentPlaybackRate, showDisplay);
                    break;
                case "up":
                    // currentPlaybackRate += speedStep; // uncomment to actually modify the playback speed
                    showDisplay = true;
                    setPlaybackRate(currentPlaybackRate, showDisplay);
                    break;
            }
        });
    }
}

async function onReady() {
    addKeyListener();
    if (enhancerExtention === true) {
        var i = 0;
        do {
            await wait(200);
            i++
        } while (!document.getElementById("enhancer-for-youtube-toolbar") && i < 50);
        onExtentionReady(); // Or setTimeout(onReady, 0); if you want it consistently async
    }
}

function wait(time) {
    return new Promise(resolve => {
        setTimeout(() => {
            resolve();
        }, time);
    });
}

function onExtentionReady() {
    addWheelListener();
}

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址