From 48a2a131632049d3275634f126986d138fc4fc5a Mon Sep 17 00:00:00 2001 From: Araxeus <78568641+Araxeus@users.noreply.github.com> Date: Sat, 30 Oct 2021 12:00:29 +0300 Subject: [PATCH] fix playback speed plugin --- plugins/playback-speed/front.js | 104 +++++++++---------- plugins/playback-speed/templates/slider.html | 1 + providers/dom-elements.js | 21 +--- 3 files changed, 51 insertions(+), 75 deletions(-) diff --git a/plugins/playback-speed/front.js b/plugins/playback-speed/front.js index fff07fee..7d970e22 100644 --- a/plugins/playback-speed/front.js +++ b/plugins/playback-speed/front.js @@ -1,83 +1,77 @@ -const { - getSongMenu, - watchDOMElement, -} = require("../../providers/dom-elements"); +const { getSongMenu } = require("../../providers/dom-elements"); const { ElementFromFile, templatePath } = require("../utils"); +function $(selector) { return document.querySelector(selector); } + const slider = ElementFromFile(templatePath(__dirname, "slider.html")); const MIN_PLAYBACK_SPEED = 0.25; const MAX_PLAYBACK_SPEED = 2; -let videoElement; -let playbackSpeedPercentage = 50; // = Playback speed of 1 +let playbackSpeed = 1; -const computePlayBackSpeed = () => { - if (playbackSpeedPercentage <= 50) { +const computePlayBackSpeed = (playbackSpeedPercentage) => { + if (playbackSpeedPercentage <= 50) { // = Playback speed <= 1 // Slow down video by setting a playback speed between MIN_PLAYBACK_SPEED and 1 return ( MIN_PLAYBACK_SPEED + ((1 - MIN_PLAYBACK_SPEED) / 50) * playbackSpeedPercentage - ); + ).toFixed(2); } // Accelerate video by setting a playback speed between 1 and MAX_PLAYBACK_SPEED - return 1 + ((MAX_PLAYBACK_SPEED - 1) / 50) * (playbackSpeedPercentage - 50); + return (1 + ((MAX_PLAYBACK_SPEED - 1) / 50) * (playbackSpeedPercentage - 50)).toFixed(2); }; const updatePlayBackSpeed = () => { - const playbackSpeed = Math.round(computePlayBackSpeed() * 100) / 100; + $('video').playbackRate = playbackSpeed; - if (!videoElement || videoElement.playbackRate === playbackSpeed) { - return; - } - - videoElement.playbackRate = playbackSpeed; - - const playbackSpeedElement = document.querySelector("#playback-speed-value"); + const playbackSpeedElement = $("#playback-speed-value"); if (playbackSpeedElement) { playbackSpeedElement.innerHTML = playbackSpeed; } }; -module.exports = () => { - watchDOMElement( - "video", - (document) => document.querySelector("video"), - (element) => { - videoElement = element; - updatePlayBackSpeed(); +let menu; + +const observePopupContainer = () => { + const observer = new MutationObserver(() => { + if (!menu) { + menu = getSongMenu(); } - ); - watchDOMElement( - "menu", - (document) => getSongMenu(document), - (menuElement) => { - if (!menuElement.contains(slider)) { - menuElement.prepend(slider); - } - - const playbackSpeedElement = document.querySelector( - "#playback-speed-slider #sliderKnob .slider-knob-inner" - ); - - const playbackSpeedObserver = new MutationObserver((mutations) => { - mutations.forEach(function (mutation) { - if (mutation.type == "attributes") { - const value = playbackSpeedElement.getAttribute("value"); - playbackSpeedPercentage = parseInt(value, 10); - if (isNaN(playbackSpeedPercentage)) { - playbackSpeedPercentage = 50; - } - updatePlayBackSpeed(); - return; - } - }); - }); - playbackSpeedObserver.observe(playbackSpeedElement, { - attributes: true, - }); + if (menu && !menu.contains(slider)) { + menu.prepend(slider); + $('#playback-speed-slider').addEventListener("immediate-value-change", () => { + playbackSpeed = computePlayBackSpeed($('#playback-speed-slider #sliderBar').value); + if (isNaN(playbackSpeed)) { + playbackSpeed = 1; + } + updatePlayBackSpeed(); + }) } - ); + }); + + observer.observe($('ytmusic-popup-container'), { + childList: true, + subtree: true, + }); +}; + +const observeVideo = () => { + $('video').addEventListener('ratechange', forcePlaybackRate) + $('video').addEventListener('loadeddata', forcePlaybackRate) +} + +function forcePlaybackRate (e) { + if (e.target.playbackRate !== playbackSpeed) { + e.target.playbackRate = playbackSpeed + } +} + +module.exports = () => { + document.addEventListener('apiLoaded', e => { + observePopupContainer(); + observeVideo(); + }) }; diff --git a/plugins/playback-speed/templates/slider.html b/plugins/playback-speed/templates/slider.html index 85865af0..d12e00e9 100644 --- a/plugins/playback-speed/templates/slider.html +++ b/plugins/playback-speed/templates/slider.html @@ -13,6 +13,7 @@ { - const observer = new MutationObserver((mutations, observer) => { - if (!domElements[name]) { - domElements[name] = selectorFn(document); - } - - if (domElements[name]) { - cb(domElements[name]); - } - }); - - observer.observe(document, { - childList: true, - subtree: true, - }); -}; - const getSongMenu = () => document.querySelector("ytmusic-menu-popup-renderer tp-yt-paper-listbox"); -module.exports = { getSongMenu, watchDOMElement }; +module.exports = { getSongMenu };