Modify the YouTube HTML player interface
目前為
// ==UserScript==
// @name YouTube Quick Speed Interface
// @name:en YouTube Quick Speed Interface
// @namespace https://twitter.com/CobleeH
// @version 1.10
// @description Modify the YouTube HTML player interface
// @description:en Modify the YouTube HTML player interface
// @author CobleeH
// @match https://www.youtube.com/*
// @grant none
// @license MIT
// ==/UserScript==
(function() {
'use strict';
// Add speed options
function addSpeedOptions() {
// Check if speed options are already added
if (document.querySelector('.ytp-speed-options')) {
return;
}
var rightControls = document.querySelector('.ytp-right-controls');
var leftControls = document.querySelector('.ytp-left-controls');
if (rightControls && leftControls) {
var speedOptions = document.createElement('div');
speedOptions.classList.add('ytp-speed-options');
speedOptions.style.display = 'flex';
speedOptions.style.alignItems = 'center';
speedOptions.style.order = '2';
speedOptions.style.marginLeft = '10px';
speedOptions.style.marginRight = '25px';
var label = document.createElement('span');
label.innerText = 'Speed';
speedOptions.appendChild(label);
var speeds = [0.5, 1, 1.5, 2];
speeds.forEach(function(speed) {
var option = document.createElement('div');
option.innerText = speed + 'x';
option.classList.add('ytp-speed-option');
option.style.cursor = 'pointer';
option.style.marginLeft = '5px';
option.addEventListener('click', function() {
var player = document.querySelector('.video-stream');
if (player) {
player.playbackRate = speed;
highlightOption(option);
}
});
option.addEventListener('mouseover', function() {
option.classList.add('highlighted');
});
option.addEventListener('mouseout', function() {
if (!option.classList.contains('active')) {
option.classList.remove('highlighted');
}
});
speedOptions.appendChild(option);
});
leftControls.style.order = '1';
rightControls.style.order = '3';
document.querySelector('.ytp-chrome-controls').appendChild(speedOptions);
}
}
function highlightOption(option) {
// Remove highlight from other options
var options = document.querySelectorAll('.ytp-speed-option');
options.forEach(function(opt) {
opt.classList.remove('active');
});
// Add highlight to the current option
option.classList.add('active');
}
// Add highlight styles
var style = document.createElement('style');
style.innerHTML = `
.ytp-speed-option {
transition: background-color 0.3s;
}
.ytp-speed-option:hover {
background-color: rgba(211, 211, 211, 0.4);
}
.ytp-speed-option.active,
.ytp-speed-option.active:hover {
background-color: rgba(211, 211, 211, 0.4);
}
`;
document.head.appendChild(style);
// Listen for URL changes and automatically reset speed highlight to 1x
var currentURL = window.location.href;
setInterval(function() {
var newURL = window.location.href;
if (newURL !== currentURL) {
// Reset speed options highlight on URL change
var options = document.querySelectorAll('.ytp-speed-option');
options.forEach(function(opt) {
opt.classList.remove('active');
});
// Set 1x speed option as highlighted
var oneXOption = document.querySelector('.ytp-speed-option:nth-child(3)'); // 1x is at the third position
if (oneXOption) {
oneXOption.classList.add('active');
}
// Update currentURL
currentURL = newURL;
}
}, 500); // Check for URL changes every 0.5 seconds
// Use MutationObserver to listen for changes in the player container element
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
// Check for newly added nodes
if (mutation.addedNodes) {
Array.from(mutation.addedNodes).forEach(function(node) {
if (node.classList && node.classList.contains('html5-video-player')) {
// Add speed options when the player container element changes
addSpeedOptions();
}
});
}
});
});
// Observe changes in the entire document
observer.observe(document.documentElement, { childList: true, subtree: true });
// Add speed options after the page is fully loaded
document.addEventListener('DOMContentLoaded', function() {
addSpeedOptions();
});
})();