您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Shows file size for each quality in YouTube
当前为
// ==UserScript== // @name YouTube Qualities Size // @namespace http://tampermonkey.net // @version 1.1.1 // @description Shows file size for each quality in YouTube // @author Abdelrahman Khalil // @match https://www.youtube.com/* // @grant none // ==/UserScript== const API = 'https://www.youtube.com/get_video_info?video_id=' const cache = {} let videoId, settingsMenuEl, observer // Fetching Info const fetchInfo = () => { return fetch(API + videoId) } const parseResponse = data => { // Youtube sends data as url queries. // we parse it then get value of player_response which is stringified JSON. let playerResponse = JSON.parse(getQuery(data, 'player_response')) return playerResponse.streamingData.adaptiveFormats } // --------- const findFormats = (formats, quality) => { let allCodecs = [], audioCL = 0, vp9 = '' let audioFormat = formats.find( format => format.audioQuality === 'AUDIO_QUALITY_MEDIUM' && format.mimeType.includes('opus') ) if (audioFormat) audioCL = audioFormat.contentLength formats.forEach(format => { if (format.qualityLabel === quality) { let codec = format.mimeType.match(REGEX.codec)[0] let sizeMB = toMB(format.contentLength, audioCL) allCodecs.push(`${codec}: ${sizeMB} MB`) if (codec === 'vp9') vp9 = sizeMB } }) let allCodecsStr = allCodecs.join('\n') return { allCodecsStr, vp9 } } // Injection const addSizesToChildren = menu => { let qualityElements = menu.querySelectorAll('span') let formats = cache[videoId] if (!formats) return qualityElements.forEach(el => { let qualityLabel = el.textContent.replace(REGEX.qlabel, '') if (qualityLabel === 'Auto') return let { allCodecsStr, vp9 } = findFormats(formats, qualityLabel) el.innerHTML += `<yt-qualities-size style="float: right; text-align: right" title="${allCodecsStr}">${vp9} MB</yt-qualities-size>` }) } // Making sure it's /watch addEventListener('yt-page-data-updated', () => { settingsMenuEl = document.querySelector('.ytp-settings-menu') videoId = getQuery(location.search, 'v') if (location.pathname === '/watch' && !observer) { observer = new MutationObserver(async ([{ addedNodes }]) => { let node = addedNodes[0] if ( node && node.classList.contains('ytp-quality-menu') && !document.querySelector('yt-qualities-size') ) { if (!cache[videoId]) { let info = await (await fetchInfo()).text() cache[videoId] = parseResponse(info) } addSizesToChildren(node) } }) observer.observe(settingsMenuEl, { childList: true }) } }) // Utils/Helpers/Stuff const getQuery = (string, query) => new URLSearchParams(string).get(query) const toMB = (vbytes, abytes) => Math.round((parseInt(vbytes) + parseInt(abytes)) / 1048576) const REGEX = { qlabel: /\s(hd|4k|8k|16k)/i, codec: /(?<==")\w+/ }
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址