Skip to content

Instantly share code, notes, and snippets.

@Kuju29
Last active August 29, 2025 02:58
Show Gist options
  • Save Kuju29/a34cf4e362e7342991b763433b8529ca to your computer and use it in GitHub Desktop.
Save Kuju29/a34cf4e362e7342991b763433b8529ca to your computer and use it in GitHub Desktop.
เล่นวีดีโอถัดไปเฉพาะคลิปสั้นเท่านั้น
// ==UserScript==
// @name YouTube Auto Play Short
// @version 25.08.29
// @description Automatically pick and play short, high‑view videos (with optional language matching) when a video ends, falling back to endscreen if sidebar fails.
// @match *://www.youtube.com/*
// @updateURL https://gist.githubusercontent.com/Kuju29/a34cf4e362e7342991b763433b8529ca/raw/YouTube%2520Auto%2520Play%2520Short%2520Videos.user.js
// @downloadURL https://gist.githubusercontent.com/Kuju29/a34cf4e362e7342991b763433b8529ca/raw/YouTube%2520Auto%2520Play%2520Short%2520Videos.user.js
// @grant GM_registerMenuCommand
// @run-at document-start
// ==/UserScript==
(function() {
'use strict';
/* =========================
* CONFIG / CONSTANTS
* ========================= */
const settingsKey = "youtubeAutoPlaySettings";
const defaultSettings = {
maxDuration: 600,
minViews: 1_000_000,
maxAgeYears: 99,
neverwatched: true,
detectLanguage: true,
removeWhenReload: false,
removewhanreload: false,
debugDrops: false
};
const UNWATCHED_WEIGHT = 10;
const STORAGE_KEYS = { playedIds: "playedVideoIds" };
const SELECTORS = {
settingsPanel: '#settings-panel',
videoTitle: [
'h1.ytd-watch-metadata',
'#container > h1 > yt-formatted-string',
'h1.title.ytd-watch-metadata'
].join(', '),
sidebarItems: [
'yt-lockup-view-model-wiz',
'yt-lockup-view-model',
'yt-lockup-view-model.ytd-item-section-renderer',
'ytd-compact-video-renderer',
'ytd-compact-playlist-renderer'
].join(', '),
modern: {
titleLink: [
'a.yt-lockup-metadata-view-model__title',
'a.yt-lockup-metadata-view-model-wiz__title'
].join(', '),
contentImageLink: [
'a.yt-lockup-view-model__content-image',
'a.yt-lockup-view-model-wiz__content-image'
].join(', '),
titleSpan: [
'.yt-lockup-metadata-view-model__title span.yt-core-attributed-string',
'.yt-lockup-metadata-view-model-wiz__title span.yt-core-attributed-string'
].join(', '),
metadataContainer: [
'.yt-lockup-view-model-wiz__metadata',
'.yt-lockup-metadata-view-model__metadata',
'.yt-lockup-metadata-view-model-wiz__metadata'
].join(', '),
metadataRow: [
'.yt-content-metadata-view-model__metadata-row',
'.yt-content-metadata-view-model-wiz__metadata-row'
].join(', '),
badgeDuration: [
'.yt-thumbnail-bottom-overlay-view-model .badge-shape-wiz__text',
'.yt-badge-shape__text',
'.badge-shape__text'
].join(', '),
watchedBar: [
'.ytThumbnailOverlayProgressBarHostWatchedProgressBarHostWatchedProgressBarSegment',
'.ytThumbnailOverlayProgressBarHostWatchedProgressBarSegment'
].join(', ')
},
autoplayToggle: '.ytp-autonav-toggle-button-container .ytp-autonav-toggle-button',
nextButton: '.ytp-next-button[aria-disabled="false"]',
endscreenItem: '.html5-endscreen .ytp-videowall-still',
endscreenTitle: '.ytp-videowall-still-info-title',
endscreenAuthor: '.ytp-videowall-still-info-author',
endscreenDuration: '.ytp-videowall-still-info-duration'
};
const EVENTS_TO_BLOCK = [
"visibilitychange","webkitvisibilitychange","blur","hasFocus",
"mouseleave","mouseout","mozvisibilitychange","msvisibilitychange"
];
const BLUR_WHITELIST = [HTMLInputElement, HTMLAnchorElement, HTMLSpanElement, HTMLParagraphElement];
const HOVER_BLACKLIST = [HTMLIFrameElement, HTMLHtmlElement, HTMLBodyElement, HTMLHeadElement, HTMLFrameSetElement, HTMLFrameElement];
const REGEX = {
videoId: /[?&]v=([^&]+)/,
viewsSuffix: /(views?|การดู)/i,
durationSplit: /:/,
ageYear: /(\d+)\s*(ปี|year|years)/i,
ageMonth: /(\d+)\s*(เดือน|month|months)/i,
ageWeek: /(\d+)\s*(สัปดาห์|week|weeks)/i,
ageDay: /(\d+)\s*(วัน|day|days)/i,
ageHour: /(\d+)\s*(ชั่วโมง|hour|hours)/i,
ageMinute: /(\d+)\s*(นาที|minute|minutes)/i
};
const LANG_PATTERNS = {
thai: /[\u0E00-\u0E7F]/,
lao: /[\u0E80-\u0EFF]/,
korean: /[\uAC00-\uD7AF]/,
japanese: /[\u3040-\u30FF]/,
cjk: /[\u4E00-\u9FFF]/
};
/* =========================
* SETTINGS UI
* ========================= */
function loadSettings() {
const saved = localStorage.getItem(settingsKey);
if (!saved) return;
try {
const parsed = JSON.parse(saved);
Object.assign(defaultSettings, parsed);
if (parsed.removewhanreload && !parsed.removeWhenReload) {
defaultSettings.removeWhenReload = true;
}
} catch(e){ console.error("Failed to parse settings:", e); }
}
function saveSettingsFromUI() {
defaultSettings.maxDuration = parseInt(document.getElementById('setting-maxDuration').value, 10);
defaultSettings.minViews = parseInt(document.getElementById('setting-minViews').value, 10);
defaultSettings.maxAgeYears = parseInt(document.getElementById('setting-maxAgeYears').value, 10);
defaultSettings.neverwatched = document.getElementById('setting-neverwatched').checked;
defaultSettings.detectLanguage= document.getElementById('setting-detectLanguage').checked;
defaultSettings.removeWhenReload = document.getElementById('setting-removeWhenReload').checked;
defaultSettings.debugDrops = document.getElementById('setting-debugDrops').checked;
localStorage.setItem(settingsKey, JSON.stringify(defaultSettings));
console.log("Settings saved:", defaultSettings);
}
function createSettingsUI() {
if (document.querySelector(SELECTORS.settingsPanel)) return;
const container = document.createElement('div');
container.id='settings-panel';
Object.assign(container.style,{
position:'fixed',top:'0',right:'0',width:'300px',
background:'linear-gradient(135deg, rgb(24 24 25) 0%, rgb(84 27 141) 100%)',
color:'#fff',borderRadius:'8px 0 0 8px',boxShadow:'0 2px 10px rgba(0,0,0,0.3)',
padding:'20px',fontFamily:'sans-serif',fontSize:'14px',opacity:'0.95',zIndex:9999
});
container.innerHTML = `
<div style="text-align:right;"><button id="close-settings">X</button></div>
<h3 style="margin:0 0 10px 0;">Auto Short Play Settings</h3>
<div style="margin-bottom:5px;">
<label>Max Duration (sec)</label>
<input type="number" id="setting-maxDuration" value="${defaultSettings.maxDuration}" style="width:100%;" />
</div>
<div style="margin-bottom:5px;">
<label>Min Views</label>
<input type="number" id="setting-minViews" value="${defaultSettings.minViews}" style="width:100%;" />
</div>
<div style="margin-bottom:5px;">
<label>Max Age (years)</label>
<input type="number" id="setting-maxAgeYears" value="${defaultSettings.maxAgeYears}" style="width:100%;" />
</div>
<div style="margin-bottom:5px;">
<label><input type="checkbox" id="setting-neverwatched" ${defaultSettings.neverwatched?'checked':''}/> Prioritize Unwatched</label>
</div>
<div style="margin-bottom:5px;">
<label><input type="checkbox" id="setting-detectLanguage" ${defaultSettings.detectLanguage?'checked':''}/> Language Match</label>
</div>
<div style="margin-bottom:5px;">
<label><input type="checkbox" id="setting-removeWhenReload" ${defaultSettings.removeWhenReload?'checked':''}/> Reset Played on Reload</label>
</div>
<div style="margin-bottom:5px;">
<label><input type="checkbox" id="setting-debugDrops" ${defaultSettings.debugDrops?'checked':''}/> Debug Dropped Items</label>
</div>
<div style="text-align:right;margin-top:10px;">
<button id="save-settings">Save</button>
</div>`;
document.body.appendChild(container);
container.querySelector('#close-settings').onclick=()=>{ container.style.display='none'; };
container.querySelector('#save-settings').onclick=()=>{ saveSettingsFromUI(); container.style.display='none'; };
}
function showSettingsUI(){ loadSettings(); if(!document.querySelector(SELECTORS.settingsPanel)) createSettingsUI(); else document.querySelector(SELECTORS.settingsPanel).style.display='block'; }
if (typeof GM_registerMenuCommand!=='undefined') GM_registerMenuCommand("Short Play Settings", showSettingsUI);
/* =========================
* UTILITIES
* ========================= */
const safeDefine=(o,k,d)=>{try{Object.defineProperty(o,k,d);}catch(e){}};
function getVideoIdFromUrl(url){ const m=url.match(REGEX.videoId); return m?m[1]:null; }
function parseDuration(str){
if(!str) return 0;
return str.trim().split(':').reverse().map(Number)
.reduce((acc,v,i)=>acc+ (Number.isFinite(v)?v:0)*60**i,0);
}
function extractDurationFallbackFromAria(linkEl){
if(!linkEl) return 0;
const raw = (linkEl.getAttribute('aria-label') || '').trim();
if(!raw) return 0;
const aria = raw.replace(/\b(LIVE|Premiering|ชมสด)\b/gi,'').trim();
const hms = (h=0,m=0,s=0) => (h*3600 + m*60 + s);
let m = aria.match(/(\d+)\s*:\s*(\d{1,2})\s*:\s*(\d{1,2})/);
if(m) return hms(+m[1], +m[2], +m[3]);
m = aria.match(/(?<!\d)(\d{1,3})\s*:\s*(\d{2})(?!\d)/);
if(m) return hms(0, +m[1], +m[2]);
// 2) ภาษา/สัญลักษณ์หลายแบบ (มีชั่วโมงก็รองรับ)
// อังกฤษ: "1 hour 2 minutes 3 seconds", "1h 2m 3s", "1 hr 2 min"
m = aria.match(/(\d+)\s*h(?:ours?)?(?:[,\s]+(\d+)\s*m(?:in(?:utes?)?)?)?(?:[,\s]+(\d+)\s*s(?:ec(?:onds?)?)?)?/i);
if(m) return hms(+m[1], m[2]?+m[2]:0, m[3]?+m[3]:0);
// อังกฤษ: "8 minutes, 21 seconds"
m = aria.match(/(\d+)\s*minutes?(?:[,\s]+(\d+)\s*seconds?)?/i);
if(m) return hms(0, +m[1], m[2]?+m[2]:0);
// อังกฤษ: "X seconds" อย่างเดียว
m = aria.match(/(\d+)\s*seconds?/i);
if(m) return hms(0, 0, +m[1]);
// ไทย: "1 ชั่วโมง 2 นาที 3 วินาที" / "8 นาที และ 21 วินาที"
m = aria.match(/(\d+)\s*ชั่วโมง(?:\s*(\d+)\s*นาที)?(?:\s*(\d+)\s*วินาที)?/);
if(m) return hms(+m[1], m[2]?+m[2]:0, m[3]?+m[3]:0);
m = aria.match(/(\d+)\s*นาที(?:\s*(?:และ\s*)?(\d+)\s*วินาที)?/);
if(m) return hms(0, +m[1], m[2]?+m[2]:0);
m = aria.match(/(\d+)\s*วินาที/);
if(m) return hms(0, 0, +m[1]);
// ญี่ปุ่น: "1時間 2分 3秒"
m = aria.match(/(\d+)\s*時間(?:\s*(\d+)\s*分)?(?:\s*(\d+)\s*秒)?/);
if(m) return hms(+m[1], m[2]?+m[2]:0, m[3]?+m[3]:0);
// เกาหลี: "1시간 2분 3초"
m = aria.match(/(\d+)\s*시간(?:\s*(\d+)\s*분)?(?:\s*(\d+)\s*초)?/);
if(m) return hms(+m[1], m[2]?+m[2]:0, m[3]?+m[3]:0);
// จีน: "1小时 2分钟 3秒"
m = aria.match(/(\d+)\s*小时(?:\s*(\d+)\s*分钟)?(?:\s*(\d+)\s*秒)?/);
if(m) return hms(+m[1], m[2]?+m[2]:0, m[3]?+m[3]:0);
// 3) กันรูปย่อแบบติดกัน เช่น "1h2m", "2m10s"
m = aria.match(/(?:(\d+)h)?(?:(\d+)m)?(?:(\d+)s)?/i);
if(m && (m[1]||m[2]||m[3])) return hms(m[1]?+m[1]:0, m[2]?+m[2]:0, m[3]?+m[3]:0);
return 0;
}
function shuffleArray(a){for(let i=a.length-1;i>0;i--){const j=Math.floor(Math.random()*(i+1));[a[i],a[j]]=[a[j],a[i]];}return a;}
function pickRandom(a){ if(!a.length) return null; return a[Math.floor(Math.random()*a.length)]; }
function detectLanguage(text){
if(!defaultSettings.detectLanguage) return 'unknown';
const t=String(text||'');
if(LANG_PATTERNS.thai.test(t)) return 'thai';
if(LANG_PATTERNS.lao.test(t)) return 'lao';
if(LANG_PATTERNS.korean.test(t)) return 'korean';
if(LANG_PATTERNS.japanese.test(t)) return 'japanese';
if(LANG_PATTERNS.cjk.test(t)) return 'chinese';
return 'unknown';
}
function getCurrentVideoLanguage(){
const el=document.querySelector(SELECTORS.videoTitle);
return el?detectLanguage(el.textContent.trim()):'unknown';
}
/* =========================
* PARSERS
* ========================= */
function parseViews(text){
if(!text) return 0;
let t=text.replace(/,/g,'').trim();
t=t.replace(/การดู/g,'').replace(/ครั้ง/g,'').replace(/views?/ig,'').trim();
let factor=1;
if (/แสน/.test(t)) { factor=100000; t=t.replace(/แสน/,'').trim(); }
else if (/หมื่น/.test(t)) { factor=10000; t=t.replace(/หมื่น/,'').trim(); }
else if (/พันล้าน/.test(t)) { factor=1e9; t=t.replace(/พันล้าน/,'').trim(); }
else if (/ล้าน/.test(t)) { factor=1e6; t=t.replace(/ล้าน/,'').trim(); }
else if (/พัน/.test(t)) { factor=1e3; t=t.replace(/พัน/,'').trim(); }
if (/b$/i.test(t)) { factor=1e9; t=t.replace(/b$/i,''); }
else if (/m$/i.test(t)) { factor=1e6; t=t.replace(/m$/i,''); }
else if (/k$/i.test(t)) { factor=1e3; t=t.replace(/k$/i,''); }
const num=parseFloat(t.replace(/[^\d\.]/g,''));
if(!isFinite(num)) return 0;
return Math.round(num*factor);
}
function parseUploadAge(text){
if(!text) return 0;
const t=text.toLowerCase().trim();
if (/(อัปเดตแล้ววันนี้|วันนี้|ใหม่\b)/.test(t)) return 0;
const mYear=t.match(REGEX.ageYear); if(mYear) return +mYear[1];
const mMonth=t.match(REGEX.ageMonth); if(mMonth) return Math.floor(+mMonth[1]/12);
const mWeek=t.match(REGEX.ageWeek); if(mWeek) return Math.floor(+mWeek[1]/52);
const mDay=t.match(REGEX.ageDay); if(mDay) return Math.floor(+mDay[1]/365);
const mHour=t.match(REGEX.ageHour); if(mHour) return 0;
const mMin=t.match(REGEX.ageMinute); if(mMin) return 0;
return 0;
}
function getVideoInfo(item){
const titleLink = item.querySelector(SELECTORS.modern.titleLink) ||
item.querySelector(SELECTORS.modern.contentImageLink);
const titleSpan = item.querySelector(SELECTORS.modern.titleSpan);
const title = titleSpan?.textContent.trim() ||
titleLink?.getAttribute('title') ||
titleLink?.ariaLabel || '';
const rows = Array.from(item.querySelectorAll(SELECTORS.modern.metadataRow));
let views = 0, age = 0;
for (const r of rows) {
const txt = r.textContent.trim();
if (/การดู|views?/i.test(txt)) {
const parts = txt.split(/•/).map(s=>s.trim());
if (parts.length>=1) views = parseViews(parts[0]);
if (parts.length>=2) age = parseUploadAge(parts[1]);
} else if (!views && /แสน|ล้าน|หมื่น|พันครั้ง|ครั้ง|views?/i.test(txt)) {
views = parseViews(txt);
} else if (!age && /(ปี|เดือน|สัปดาห์|วัน|อัปเดตแล้ววันนี้|วันนี้|ใหม่|month|year|week|day|hour|min)/i.test(txt)) {
age = parseUploadAge(txt);
}
}
const durationText = item.querySelector(SELECTORS.modern.badgeDuration)?.textContent.trim() || '';
let duration = parseDuration(durationText) || extractDurationFallbackFromAria(titleLink);
const progress = !!item.querySelector(SELECTORS.modern.watchedBar);
const href = titleLink?.getAttribute('href') || '';
return { title, views, age, duration, progress, href };
}
/* =========================
* ENDSCREEN FALLBACK
* ========================= */
function parseViewsSimple(v){ return parseViews(v); }
function getEndscreenData(node){
const url=node.getAttribute('href')||'';
const title=node.querySelector(SELECTORS.endscreenTitle)?.textContent.trim()||'';
const author=node.querySelector(SELECTORS.endscreenAuthor)?.textContent.trim()||'';
const durText=node.querySelector(SELECTORS.endscreenDuration)?.textContent.trim()||'0:00';
const [channel, viewsStr]=author.split('•').map(s=>s.trim());
return { url, title, channel:channel||'', views:parseViewsSimple(viewsStr||''), duration:parseDuration(durText) };
}
function fallbackToNextButton(){
const btn=document.querySelector(SELECTORS.nextButton);
if(!btn){ console.log("[AutoShort] No next button"); return; }
btn.click();
}
function pickVideoFromEndscreen(){
const items=document.querySelectorAll(SELECTORS.endscreenItem);
if(!items.length){ fallbackToNextButton(); return; }
const candidates=[];
items.forEach(v=>{
if(!v.closest('.html5-endscreen')) return;
const d=getEndscreenData(v);
if(d.duration<defaultSettings.maxDuration && d.views>=defaultSettings.minViews){
candidates.push({duration:d.duration,views:d.views,age:0,lang:detectLanguage(d.title),title:d.title,element:v});
}
});
if(!candidates.length){ fallbackToNextButton(); return; }
pickRandom(candidates)?.element?.click();
}
/* =========================
* AUTOPLAY CORE
* ========================= */
let playedVideoIds=[];
try{
const stored=sessionStorage.getItem(STORAGE_KEYS.playedIds);
if(stored) playedVideoIds=JSON.parse(stored);
}catch(e){}
function savePlayedVideoIds(){
sessionStorage.setItem(STORAGE_KEYS.playedIds, JSON.stringify(playedVideoIds));
}
function matchesLanguage(videoLang, currentLang) {
if (!defaultSettings.detectLanguage) return true;
if (currentLang === 'unknown') return true;
return videoLang === currentLang;
}
function mainAutoPlay(){
console.log("== [AutoShort mainAutoPlay] ==");
const autoplayBtn=document.querySelector(SELECTORS.autoplayToggle);
if(!autoplayBtn) return;
if(autoplayBtn.getAttribute('aria-checked')!=='false'){ return; }
if(location.href.includes('list=')) return; // Skip playlists
const sidebarItems=Array.from(document.querySelectorAll(SELECTORS.sidebarItems));
if(!sidebarItems.length){
console.log("[AutoShort] No sidebar items -> using endscreen");
pickVideoFromEndscreen(); return;
}
const videoData = sidebarItems.map(item=>{
const info = getVideoInfo(item);
if(!info || !info.title) return null;
const videoId = getVideoIdFromUrl(info.href||'');
const lang = detectLanguage(info.title);
return {
duration: info.duration,
views: info.views,
age: info.age,
lang,
title: info.title,
videoId,
element: item.querySelector(SELECTORS.modern.titleLink) || item.querySelector(SELECTORS.modern.contentImageLink),
progress: info.progress
};
}).filter(Boolean);
console.log("[AutoShort] Raw items:", videoData);
const currentLang=getCurrentVideoLanguage();
if (defaultSettings.debugDrops) {
videoData.forEach(v=>{
const reasons=[];
if (v.duration >= defaultSettings.maxDuration) reasons.push('duration');
if (v.views < defaultSettings.minViews) reasons.push('views');
if (!matchesLanguage(v.lang,currentLang)) reasons.push('lang');
if (!v.videoId) reasons.push('noId');
if (playedVideoIds.includes(v.videoId)) reasons.push('played');
if (v.age > defaultSettings.maxAgeYears) reasons.push('age');
if (reasons.length) console.debug('[DROP]', v.title, reasons.join('|'), v);
});
}
const candidates=videoData.filter(v =>
v.duration < defaultSettings.maxDuration &&
v.views >= defaultSettings.minViews &&
matchesLanguage(v.lang, currentLang) &&
v.videoId &&
!playedVideoIds.includes(v.videoId) &&
v.age <= defaultSettings.maxAgeYears
);
if(!candidates.length){
console.log("[AutoShort] No candidates => endscreen fallback");
pickVideoFromEndscreen(); return;
}
const weighted = defaultSettings.neverwatched
? candidates.flatMap(v => Array(v.progress ? 1 : UNWATCHED_WEIGHT).fill(v))
: candidates;
const picked=pickRandom(weighted);
if(!picked){ pickVideoFromEndscreen(); return; }
console.log("[AutoShort] Filtered:", candidates);
console.log("[AutoShort] Playing:", picked.element?.href || picked.element?.getAttribute('href'));
playedVideoIds.push(picked.videoId);
savePlayedVideoIds();
picked.element?.click();
}
/* =========================
* VISIBILITY BLOCK
* ========================= */
(function overrideVisibility(){
if (typeof unsafeWindow!=='undefined'){
unsafeWindow.onblur=null; unsafeWindow.blurred=false;
unsafeWindow.document.hasFocus=()=>true;
unsafeWindow.window.onFocus=()=>true;
} else {
window.onblur=null;
document.hasFocus=()=>true;
window.onFocus=()=>true;
}
['hidden','mozHidden','msHidden','webkitHidden'].forEach(k=>safeDefine(document,k,{get:()=>false}));
safeDefine(document,'visibilityState',{get:()=> 'visible'});
safeDefine(document,'webkitVisibilityState',{get:()=> 'visible'});
if (typeof unsafeWindow!=='undefined') unsafeWindow.document.onvisibilitychange=undefined;
else document.onvisibilitychange=undefined;
const handler=e=>{
if(e.type==='blur' && (BLUR_WHITELIST.some(t=>e.target instanceof t) ||
(e.target.classList && e.target.classList.contains('ql-editor')))) return;
if(['mouseleave','mouseout'].includes(e.type) && !HOVER_BLACKLIST.some(t=>e.target instanceof t)) return;
e.preventDefault(); e.stopPropagation(); e.stopImmediatePropagation();
};
EVENTS_TO_BLOCK.forEach(ev=>{
window.addEventListener(ev,handler,true);
document.addEventListener(ev,handler,true);
});
})();
/* =========================
* INIT & OBSERVER
* ========================= */
let lastUrl=location.href;
function shouldRunScript(){
return location.hostname==='www.youtube.com' &&
location.href.includes('watch?') &&
!location.href.includes('&list=');
}
function init(){
if(!shouldRunScript()) return;
loadSettings();
const currentId=getVideoIdFromUrl(location.href);
if(currentId && !playedVideoIds.includes(currentId)){
playedVideoIds.push(currentId); savePlayedVideoIds();
}
const video=document.querySelector('video');
if(video && !video.dataset.autoPlayEventAdded){
video.dataset.autoPlayEventAdded='true';
video.addEventListener('ended', ()=> mainAutoPlay());
}
}
const observer=new MutationObserver(()=>{
if(location.href!==lastUrl){
lastUrl=location.href;
setTimeout(()=>{ if(shouldRunScript()) init(); },1500);
}
});
function startObserver(){
if(document.body) observer.observe(document.body,{childList:true,subtree:true});
else document.addEventListener('DOMContentLoaded',()=>observer.observe(document.body,{childList:true,subtree:true}));
}
function delayedInit(){ setTimeout(init,500); }
if(document.readyState==='loading') document.addEventListener('DOMContentLoaded',delayedInit);
else delayedInit();
startObserver();
if(defaultSettings.removeWhenReload || defaultSettings.removewhanreload){
window.addEventListener('beforeunload',()=>sessionStorage.removeItem(STORAGE_KEYS.playedIds));
}
})();
@Kuju29
Copy link
Author

Kuju29 commented May 8, 2025

image
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment