Last active
March 9, 2026 15:35
-
-
Save htsign/cc246428156299e2028e87813d3b95d8 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // ==UserScript== | |
| // @name Embedded YouTube fix | |
| // @description this monitors and auto-refreshes crashed embedded YouTube players in the background for a seamless viewing experience | |
| // @namespace https://htsign.hateblo.jp | |
| // @version 0.5.5 | |
| // @author htsign | |
| // @match *://*/* | |
| // @match https://www.youtube.com/embed/* | |
| // @updateURL https://gist.github.com/htsign/cc246428156299e2028e87813d3b95d8/raw/Embedded-YouTube-fix.user.js | |
| // @downloadURL https://gist.github.com/htsign/cc246428156299e2028e87813d3b95d8/raw/Embedded-YouTube-fix.user.js | |
| // @grant none | |
| // @license MIT | |
| // ==/UserScript== | |
| (() => { | |
| 'use strict'; | |
| const ID = 'embedded-youtube-fix'; | |
| /** @type {RegExp[]} */ | |
| const BROKEN_PAGES = []; | |
| const iframes = document.getElementsByTagName('iframe'); | |
| // parent | |
| if (window.self === window.top) { | |
| /** | |
| * tracks visible iframes and the timestamp of the last message sent | |
| * | |
| * @type {WeakMap<HTMLIFrameElement, number>} | |
| */ | |
| const visibles = new WeakMap(); | |
| /** | |
| * @param {HTMLIFrameElement} target | |
| */ | |
| const postId = target => target.contentWindow?.postMessage(ID, 'https://www.youtube.com'); | |
| const observer = new IntersectionObserver(entries => { | |
| for (const { target, isIntersecting } of entries) { | |
| if (isIntersecting) { | |
| const current = performance.now(); | |
| if (!visibles.has(target) || current - visibles.get(target) > 1000) { | |
| postId(target); | |
| } | |
| visibles.set(target, current); | |
| } | |
| else { | |
| visibles.delete(target); | |
| } | |
| } | |
| }); | |
| window.addEventListener('message', ({ data, source, origin }) => { | |
| if (origin !== 'https://www.youtube.com') return; | |
| if (data !== ID) return; | |
| const iframe = Array.prototype.find.call(iframes, el => el.contentWindow === source); | |
| if (iframe == null) return; | |
| if (!iframe.hasAttribute('referrerpolicy')) { | |
| iframe.setAttribute('referrerpolicy', 'strict-origin-when-cross-origin'); | |
| return; | |
| } | |
| const url = new URL(iframe.src); | |
| if ( | |
| ['playlist', 'videoseries'].some(path => url.pathname.endsWith(`/${path}`)) | |
| && url.searchParams.has('list') | |
| && url.searchParams.has('feature') | |
| ) { | |
| url.searchParams.delete('feature'); | |
| } | |
| if (url.searchParams.get('feature') === 'oembed') { | |
| url.searchParams.delete('feature'); | |
| } | |
| url.searchParams.set(ID, url.searchParams.get(ID) ^ 1); | |
| if (BROKEN_PAGES.some(pageRegex => pageRegex.test(url.href))) { | |
| // fallback for cases where copying elements breaks the original site's scripts | |
| iframe.src = url.toString(); | |
| } | |
| else { | |
| // avoid multiple back button presses | |
| const newIframe = iframe.cloneNode(); | |
| newIframe.src = url.toString(); | |
| iframe.replaceWith(newIframe); | |
| observer.observe(newIframe); | |
| } | |
| }); | |
| const loop = () => { | |
| for (const iframe of iframes) { | |
| observer.observe(iframe); | |
| if (visibles.has(iframe)) { | |
| postId(iframe); | |
| } | |
| } | |
| setTimeout(loop, 500); | |
| }; | |
| requestIdleCallback(loop); | |
| } | |
| // inside of iframe | |
| else if (location.href.startsWith('https://www.youtube.com/embed/')) { | |
| window.addEventListener('message', ({ data, source, origin }) => { | |
| if (data !== ID) return; | |
| const error = document.querySelector('.ytp-error'); | |
| const subreason = error?.querySelector('.ytp-error-content-wrap-subreason'); | |
| if (subreason && getComputedStyle(subreason).display !== 'none') { | |
| source.postMessage(ID, origin); | |
| } | |
| }); | |
| } | |
| })(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment