// ==UserScript== // @name YouTube double speed, excluding LIVE or brief video(such as music) // @namespace https://tangled.org/lamrongol.bsky.social/YouTubeAutoSpeed // @version 0.1.0 // @description Auto set YouTube speed fast, but not for LIVE, brief video, AMSR and "歌枠". // @author @lamrongol // @match https://*.youtube.com/* // @match https://m.youtube.com/* // @icon https://www.google.com/s2/favicons?sz=64&domain=www.youtube.com // @license MIT // @grant none // ==/UserScript== (function () { 'use strict'; const main = _event => { if (document.readyState == 'complete') { if (document.location.pathname == "/live_chat") return; document.removeEventListener('readystatechange', main); //https://learn.scriptcat.org/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98/%E5%B8%B8%E8%A7%81%E8%AF%AF%E5%8C%BA1/ let ops = document.querySelector("ytd-app"); let videoFoundUrl = ""; setTimeout(() => { let observer = new MutationObserver(function (_mutations) { if (document.location.pathname != "/watch") return; const video = document.querySelector('video'); if (video && video.readyState > 3) { if (document.location.href == videoFoundUrl) return; videoFoundUrl = document.location.href; let isLive = document.querySelector(".ytp-live-badge-is-livehead"); let is_long = false; if (!isLive) { const span_list = document.getElementsByClassName("ytp-time-duration"); if (span_list) { const span = span_list[0]; const time = span.innerText;//e.g. "1:47:01" const list = time.split(":"); if (list.length == 1) { is_long = false; } else if (list.length > 2) { is_long = true; } else { const minutes = Number(list[0]); is_long = minutes > 5; } } } let player = document.getElementById("movie_player"); let video_main = player.querySelector('video.html5-main-video'); let video_name = document.querySelector("yt-formatted-string").getAttribute("title"); if (!is_long || isLive || video_name.includes("ASMR") || video_name.includes("歌枠")) { player.setPlaybackRate(1.0); video_main.playbackRate = 1.0; } else { player.setPlaybackRate(2.0); video_main.playbackRate = 2.0; } } }); observer.observe(ops, { childList: true, subtree: true }); }, 500); } } document.addEventListener('readystatechange', main); })();