Add plugin to control playback speed like in YouTube (from 0.25 to 2)

This commit is contained in:
TC
2021-02-07 11:46:57 +01:00
parent 3415ce3965
commit f7f31850d3
3 changed files with 195 additions and 0 deletions

View File

@ -0,0 +1,81 @@
const { watchDOMElement } = require("../../providers/dom-elements");
const { ElementFromFile, templatePath } = require("../utils");
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
const computePlayBackSpeed = () => {
if (playbackSpeedPercentage <= 50) {
// Slow down video by setting a playback speed between MIN_PLAYBACK_SPEED and 1
return (
MIN_PLAYBACK_SPEED +
((1 - MIN_PLAYBACK_SPEED) / 50) * playbackSpeedPercentage
);
}
// Accelerate video by setting a playback speed between 1 and MAX_PLAYBACK_SPEED
return 1 + ((MAX_PLAYBACK_SPEED - 1) / 50) * (playbackSpeedPercentage - 50);
};
const updatePlayBackSpeed = () => {
const playbackSpeed = Math.round(computePlayBackSpeed() * 100) / 100;
if (!videoElement || videoElement.playbackRate === playbackSpeed) {
return;
}
videoElement.playbackRate = playbackSpeed;
const playbackSpeedElement = document.querySelector("#playback-speed-value");
if (playbackSpeedElement) {
playbackSpeedElement.innerHTML = playbackSpeed;
}
};
module.exports = () => {
watchDOMElement(
"video",
(document) => document.querySelector("video"),
(element) => {
videoElement = element;
updatePlayBackSpeed();
}
);
watchDOMElement(
"menu",
(document) =>
document.querySelector("ytmusic-menu-popup-renderer paper-listbox"),
(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,
});
}
);
};

View File

@ -0,0 +1,94 @@
<div
class="menu-item ytmusic-menu-popup-renderer"
role="option"
tabindex="-1"
aria-disabled="false"
aria-selected="false"
>
<paper-slider
id="playback-speed-slider"
class="volume-slider style-scope ytmusic-player-bar on-hover"
max="100"
min="0"
step="5"
dir="ltr"
title="Playback speed"
aria-label="Playback speed"
role="slider"
tabindex="0"
aria-valuemin="0"
aria-valuemax="100"
aria-valuenow="50"
aria-disabled="false"
value="50"
><!--css-build:shady-->
<div id="sliderContainer" class="style-scope paper-slider">
<div class="bar-container style-scope paper-slider">
<paper-progress
id="sliderBar"
aria-hidden="true"
class="style-scope paper-slider"
role="progressbar"
value="50"
aria-valuenow="50"
aria-valuemin="0"
aria-valuemax="100"
aria-disabled="false"
style="touch-action: none;"
><!--css-build:shady-->
<div id="progressContainer" class="style-scope paper-progress">
<div
id="secondaryProgress"
class="style-scope paper-progress"
hidden="true"
style="transform: scaleX(0);"
></div>
<div
id="primaryProgress"
class="style-scope paper-progress"
style="transform: scaleX(0.5);"
></div>
</div>
</paper-progress>
</div>
<dom-if class="style-scope paper-slider"
><template is="dom-if"></template
></dom-if>
<div
id="sliderKnob"
class="slider-knob style-scope paper-slider"
style="left: 50%; touch-action: none;"
>
<div
class="slider-knob-inner style-scope paper-slider"
value="50"
></div>
<paper-ripple
id="ink"
center=""
class="circle style-scope paper-slider"
style="display: none;"
><!--css-build:shady-->
<div
id="background"
class="style-scope paper-ripple"
style="opacity: 0.006008;"
></div>
<div id="waves" class="style-scope paper-ripple"></div>
</paper-ripple>
</div>
</div>
<dom-if class="style-scope paper-slider"
><template is="dom-if"></template
></dom-if>
</paper-slider>
<div
class="text style-scope ytmusic-toggle-menu-service-item-renderer"
id="ytmcustom-playback-speed"
>
Speed (<span id="playback-speed-value">1</span>)
</div>
</div>