您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Add playback speed controls to plex web player with keyboard shortcuts
- // ==UserScript==
- // @name Plex Playback Speed
- // @namespace https://github.com/ZigZagT
- // @version 1.3.1
- // @description Add playback speed controls to plex web player with keyboard shortcuts
- // @author ZigZagT
- // @include /^https?://[^/]*plex[^/]*/
- // @include /^https?://[^/]*:32400/
- // @match https://app.plex.tv/
- // @match https://plex.tv/
- // @license MIT
- // ==/UserScript==
- (function() {
- 'use strict';
- const console_log = (...args) => {
- console.log(`PlexPlaybackSpeed:`, ...args)
- }
- const cycleSpeeds = [
- 0.5, 0.8, 1, 1.2, 1.4, 1.6, 1.8, 2, 2.5, 3, 3, 5, 4, 5, 6, 7, 8, 9, 10, 15, 20
- ];
- const quickSetSpeeds = {
- 1: 1,
- 2: 1.5,
- 3: 2,
- 4: 3,
- 5: 4,
- 6: 5,
- 7: 7,
- 8: 8,
- 9: 10,
- };
- function prompt(txt) {
- const existingPrompt = document.querySelector("#playback-speed-prompt");
- if (existingPrompt) {
- document.body.removeChild(existingPrompt);
- }
- const prompt = document.createElement("div");
- prompt.id = "playback-speed-prompt";
- prompt.innerText = txt;
- document.body.appendChild(prompt);
- prompt.style = `
- position: fixed;
- top: 0;
- left: 0;
- width: 8em;
- height: 2em;
- background-color: rgba(0, 0, 0, 0.5);
- color: white;
- font-size: 2em;
- text-align: center;
- z-index: 99999;
- pointer-events: none;
- `;
- setTimeout(() => {
- try {
- document.body.removeChild(prompt);
- } catch (e) {}
- }, 2000);
- }
- function getNextCycleSpeed(direction, currentSpeed) {
- let newSpeed = currentSpeed;
- for (const speed of cycleSpeeds) {
- if (direction === 'slowdown') {
- if (speed < currentSpeed) {
- newSpeed = speed;
- } else {
- break;
- }
- } else if (direction === 'speedup') {
- if (speed > currentSpeed) {
- newSpeed = speed;
- break;
- }
- } else {
- console.error(`invalid change speed direction ${direction}`)
- break;
- }
- }
- return newSpeed;
- }
- function keyboardUpdateSpeed(e) {
- const videoElem = document.querySelector("video");
- if (videoElem == null) {
- return;
- }
- const currentSpeed = videoElem.playbackRate;
- let newSpeed = currentSpeed;
- console_log({currentSpeed, key: e.key});
- if (e.key in quickSetSpeeds) {
- newSpeed = quickSetSpeeds[e.key];
- } else if (["<", ","].includes(e.key)) {
- newSpeed = getNextCycleSpeed('slowdown', currentSpeed);
- } else if ([">", "."].includes(e.key)) {
- newSpeed = getNextCycleSpeed('speedup', currentSpeed);
- } else {
- return;
- }
- console_log('change speed to', newSpeed);
- videoElem.playbackRate = newSpeed;
- prompt(`Speed: ${newSpeed}x`);
- }
- function btnSpeedUpFn() {
- const currentSpeed = document.querySelector("video").playbackRate;
- let newSpeed = getNextCycleSpeed('speedup', currentSpeed);
- console_log('change speed to', newSpeed);
- document.querySelector("video").playbackRate = newSpeed;
- prompt(`Speed: ${newSpeed}x`);
- }
- function btnSlowdownFn() {
- const currentSpeed = document.querySelector("video").playbackRate;
- let newSpeed = getNextCycleSpeed('slowdown', currentSpeed);
- console_log('change speed to', newSpeed);
- document.querySelector("video").playbackRate = newSpeed;
- prompt(`Speed: ${newSpeed}x`);
- }
- function addPlaybackButtonControls() {
- const btnStyle = `
- align-items: center;
- border-radius: 15px;
- display: flex;
- font-size: 18px;
- height: 30px;
- justify-content: center;
- margin-left: 5px;
- text-align: center;
- width: 30px;
- `;
- const containers = document.querySelectorAll('[class*="PlayerControls-buttonGroupRight"]');
- containers.forEach(container => {
- if (container.querySelector('#playback-speed-btn-slowdown')) {
- return;
- }
- const btnSlowDown = document.createElement('button');
- btnSlowDown.id = 'playback-speed-btn-slowdown';
- btnSlowDown.style = btnStyle;
- btnSlowDown.innerHTML = '🐢';
- btnSlowDown.addEventListener('click', btnSlowdownFn);
- const btnSpeedUp = document.createElement('button');
- btnSpeedUp.id = 'playback-speed-btn-speedup';
- btnSpeedUp.style = btnStyle;
- btnSpeedUp.innerHTML = '🐇';
- btnSpeedUp.addEventListener('click', btnSpeedUpFn);
- console_log('adding speed controls to', container);
- container.prepend(btnSlowDown, btnSpeedUp);
- })
- }
- function scheduleLoopFrame() {
- setTimeout(() => {
- requestAnimationFrame(() => {
- addPlaybackButtonControls();
- scheduleLoopFrame();
- });
- }, 500);
- }
- if (window.__plex_playback_speed_control_registered__) {
- console_log('plex playback speed controls are already registered');
- } else {
- window.__plex_playback_speed_control_registered__ = true;
- console_log('registering plex playback speed controls');
- window.addEventListener("keydown", keyboardUpdateSpeed);
- scheduleLoopFrame();
- }
- })();