🎉 欢迎访问GreasyFork.Org 镜像站!本镜像站由公众号【爱吃馍】搭建,用于分享脚本。联系邮箱📮

Greasy fork 爱吃馍镜像

YouTube Fixed Video Quality

Remember video quality without any additional user interface.

이 스크립트를 설치하려면 Tampermonkey, Greasemonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

You will need to install an extension such as Tampermonkey to install this script.

이 스크립트를 설치하려면 Tampermonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Userscripts와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 유저 스크립트 관리자 확장 프로그램이 필요합니다.

(이미 유저 스크립트 관리자가 설치되어 있습니다. 설치를 진행합니다!)

🚀 安装遇到问题?关注公众号获取帮助

公众号二维码

扫码关注【爱吃馍】

回复【脚本】获取最新教程和防失联地址

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

(이미 유저 스타일 관리자가 설치되어 있습니다. 설치를 진행합니다!)

🚀 安装遇到问题?关注公众号获取帮助

公众号二维码

扫码关注【爱吃馍】

回复【脚本】获取最新教程和防失联地址

// ==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.2
// @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==

(async function() {
	'use strict';

	let vidQuality = await GM.getValue( 'videoQuality', 1 );
	let player = null;

	document.addEventListener('yt-player-updated', () => {

		/* Check page type. Video url should be /watch or /live */
		if ( /^\/watch|^\/live/.test(window.location.pathname) ) {
			setVideoQuality();
		}
	});


	async function setVideoQuality() {

		/* 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)');
		if (!qualityBtn) { /* Video not loaded: stream not started or other issues. */
			detectVideoStart();
			return;
		}
		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 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].addEventListener('click', () => {
				GM.setValue( 'videoQuality', qualityOptions.length - i );
			});
		}
	}


	function detectVideoStart() {

		/* Prevent infinite loop b/w detectVideoStart() & setVideoQuality() in case sth go wrong. */
		if (player) return;

		const observer = new MutationObserver((mutations) => {
			mutations.forEach((mutation) => {
				if (mutation.type != 'attributes') return;
				if (mutation.attributeName != 'class') return;

				/* Detect when a stream starts. */
				if ( player.classList.contains('unstarted-mode') ) return;

				observer.disconnect();
				setVideoQuality();
			});
		});

		player = document.getElementById('movie_player');
		observer.observe(player, { attributes: true });
	}

})();