Remember video quality without any additional user interface.
// ==UserScript==
// @name YouTube Fixed Video Quality
// @name:zh-TW YouTube固定影片畫質
// @name:zh-CN YouTube固定视频画质
// @description Remember video quality without any additional user interface.
// @description:zh-TW 記住選取的 YouTube 影片畫質,不需任何額外的操作介面。
// @description:zh-CN 记住选取的 YouTube 视频画质,不需任何额外的操作介面。
// @license MIT
// @namespace https://greasyfork.org/users/1086571
// @version 1.3
// @author IzsKon
// @match https://www.youtube.com/*
// @icon https://raw.githubusercontent.com/IzsKon/YouTube-Fixed-Video-Quality/main/icon.png
// @grant GM.getValue
// @grant GM.setValue
// ==/UserScript==
'use strict';
const sleep = ms => new Promise(r => setTimeout(r, ms));
(function() {
let video = document.querySelector('#movie_player video');
if (video) {
video.addEventListener('playing', initVideoQuality, {once: true});
video.addEventListener('loadstart', enforceVideoQuality);
}
document.addEventListener('yt-player-updated', () => {
if (video) {
video.removeEventListener('playing', initVideoQuality);
video.removeEventListener('loadstart', enforceVideoQuality);
}
video = document.querySelector('#movie_player video');
video.addEventListener('playing', initVideoQuality, {once: true});
video.addEventListener('loadstart', enforceVideoQuality);
});
})();
async function initVideoQuality() {
/* Load settings panel. */
let settingsBtn = document.querySelector('.ytp-settings-button');
settingsBtn.click();
settingsBtn.click();
/* Open quality selection panel. */
let qualityBtn = document.querySelector('.ytp-menuitem-content div:not(.ytp-menuitem-toggle-checkbox)');
qualityBtn.click();
let qualityOptions = document.querySelectorAll('.ytp-quality-menu .ytp-menuitem:not(:has(.ytp-premium-label))');
/* Close quality selection panel. */
settingsBtn.click();
settingsBtn.click();
/* Select video quality. */
let vidQuality = await GM.getValue('videoQuality', 1);
let nth_option = qualityOptions.length - vidQuality;
qualityOptions[ Math.max(0, nth_option) ].click();
/* Add event listener to quality selection. */
for ( let i = 0; i < qualityOptions.length; ++i ) {
qualityOptions[i].onclick = () => {
GM.setValue( 'videoQuality', qualityOptions.length - i );
};
}
}
async function enforceVideoQuality() {
let vidQuality = await GM.getValue('videoQuality', 1);
let videoPlayer = document.querySelector('#movie_player');
let qualityLevels = videoPlayer.getAvailableQualityLevels();
let nth_option = Math.max(0, qualityLevels.length - vidQuality);
videoPlayer.setPlaybackQualityRange( qualityLevels[nth_option] );
}