// ==UserScript== // @name YouTube Playback Plox // @name:en YouTube Playback Plox // @name:es YouTube Reproducción Plox // @name:fr YouTube Lecture Plox // @name:de YouTube Wiedergabe Plox // @name:it YouTube Riproduzione Plox // @name:pt-BR YouTube Reprodução Plox // @name:nl YouTube Afspelen Plox // @name:pl YouTube Odtwarzanie Plox // @name:sv YouTube Uppspelning Plox // @name:da YouTube Afspilning Plox // @name:no YouTube Avspilling Plox // @name:fi YouTube Toisto Plox // @name:cs YouTube Přehrávání Plox // @name:sk YouTube Prehrávanie Plox // @name:hu YouTube Lejátszás Plox // @name:ro YouTube Redare Plox // @name:be YouTube Воспроизведение Plox // @name:bg YouTube Възпроизвеждане Plox // @name:el YouTube Αναπαραγωγή Plox // @name:sr YouTube Репродукција Plox // @name:hr YouTube Reprodukcija Plox // @name:sl YouTube Predvajanje Plox // @name:lt YouTube Grotuvas Plox // @name:lv YouTube Atskaņošana Plox // @name:uk YouTube Відтворення Plox // @name:ru YouTube Воспроизведение Plox // @name:tr YouTube Oynatma Plox // @name:ar يوتيوب بلايباك Plox // @name:fa پخش یوتیوب Plox // @name:he YouTube השמעה Plox // @name:hi YouTube प्लेबैक Plox // @name:bn YouTube প্লেব্যাক Plox // @name:te YouTube ప్లేబ్యాక్ Plox // @name:ta YouTube பிளேபாக் Plox // @name:mr YouTube प्लेबॅक Plox // @name:zh-CN YouTube 播放 Plox // @name:zh-TW YouTube 播放 Plox // @name:zh-HK YouTube 播放 Plox // @name:ja YouTube 再生 Plox // @name:ko YouTube 재생 Plox // @name:th YouTube เล่นต่อ Plox // @name:vi YouTube Phát lại Plox // @name:id YouTube Pemutaran Plox // @name:ms YouTube Main Semula Plox // @name:tl YouTube Playback Plox // @name:my YouTube ဖလေ့ဘက် Plox // @name:sw YouTube Uchezesha Plox // @name:am የYouTube ተጫዋች Plox // @name:ha YouTube Playback Plox // @name:ur YouTube پلے بیک Plox // @name:ca YouTube Reproducció Plox // @name:zu YouTube Playback Plox // @name:yue YouTube 播放 Plox // @name:es-419 YouTube Reproducción Plox // @description Guarda y retoma automáticamente el progreso de vídeos en YouTube sin necesidad de iniciar sesión. // @description:en Automatically saves and resumes video playback progress on YouTube without needing to log in. // @description:es Guarda y retoma automáticamente el progreso de vídeos en YouTube sin necesidad de iniciar sesión. // @description:fr Enregistre et reprend automatiquement la progression de la lecture des vidéos sur YouTube sans avoir besoin de se connecter. // @description:de Speichert und setzt den Fortschritt von YouTube-Videos automatisch fort, ohne dass eine Anmeldung erforderlich ist. // @description:it Salva e riprende automaticamente la riproduzione dei video su YouTube senza bisogno di accedere. // @description:pt-BR Salva e retoma automaticamente o progresso da reprodução de vídeos no YouTube sem precisar fazer login. // @description:nl Slaat automatisch de voortgang van video's op YouTube op en hervat deze zonder in te loggen. // @description:pl Automatycznie zapisuje i wznawia postęp odtwarzania wideo na YouTube bez logowania. // @description:sv Sparar och återupptar automatiskt videoframsteg på YouTube utan att behöva logga in. // @description:da Gemmer og genoptager automatisk videoafspilning på YouTube uden at logge ind. // @description:no Lagrer og gjenopptar automatisk videofremdrift på YouTube uten å logge inn. // @description:fi Tallentaa ja jatkaa automaattisesti YouTube-videoiden toistopistettä ilman kirjautumista. // @description:cs Automaticky ukládá a obnovuje postup přehrávání videí na YouTube bez nutnosti přihlášení. // @description:sk Automaticky ukladá a obnovuje priebeh prehrávania videí na YouTube bez potreby prihlásenia. // @description:hu Automatikusan menti és folytatja a YouTube-videók lejátszási előrehaladását bejelentkezés nélkül. // @description:ro Salvează și reia automat progresul redării videoclipurilor pe YouTube fără a fi nevoie să te conectezi. // @description:be Автоматично зберігає та відновлює прогрес відтворення відео на YouTube без входу в акаунт. // @description:bg Автоматично записва и възобновява прогреса на видеото в YouTube без нужда от вход. // @description:el Αποθηκεύει και συνεχίζει αυτόματα την πρόοδο αναπαραγωγής βίντεο στο YouTube χωρίς να χρειάζεται σύνδεση. // @description:sr Аутоматски чува и наставља напредак репродукције видео записа на YouTube-у без пријављивања. // @description:hr Automatski sprema i nastavlja napredak reprodukcije videozapisa na YouTubeu bez prijave. // @description:sl Samodejno shrani in nadaljuje napredek predvajanja videoposnetkov na YouTubu brez prijave. // @description:lt Automatiškai išsaugo ir atnaujina YouTube vaizdo įrašų atkūrimo pažangą be prisijungimo. // @description:lv Automātiski saglabā un atsāk video atskaņošanas progresu YouTube bez pieteikšanās. // @description:uk Автоматично зберігає та відновлює прогрес відтворення відео на YouTube без входу в акаунт. // @description:ru Автоматически сохраняет и возобновляет прогресс воспроизведения видео на YouTube без входа в аккаунт. // @description:tr YouTube'daki video oynatma ilerlemesini otomatik olarak kaydeder ve devam ettirir, giriş yapmaya gerek yok. // @description:ar يقوم بحفظ واستئناف تقدم تشغيل الفيديوهات على يوتيوب تلقائيًا دون الحاجة لتسجيل الدخول. // @description:fa پیشرفت پخش ویدیوها در یوتیوب را به صورت خودکار ذخیره و ادامه می‌دهد بدون نیاز به ورود. // @description:he שומר ומחדש אוטומטית את התקדמות הניגון של סרטונים ביוטיוב ללא צורך בהתחברות. // @description:hi YouTube पर वीडियो प्लेबैक की प्रगति को स्वचालित रूप से सहेजें और पुनः प्रारंभ करें, लॉगिन की आवश्यकता नहीं। // @description:bn YouTube ভিডিও প্লেব্যাকের অগ্রগতি স্বয়ংক্রিয়ভাবে সংরক্ষণ এবং পুনরায় শুরু করুন, লগইনের প্রয়োজন নেই। // @description:te YouTube వీడియో ప్లేబ్యాక్ పురోగతిని ఆటోమేటిక్‌గా సేవ్ చేసి, తిరిగి ప్రారంభిస్తుంది, లాగిన్ అవసరం లేదు. // @description:ta YouTube வீடியோக்களின் பிளேபாக் முன்னேற்றத்தை தானாகச் சேமித்து மீண்டும் தொடங்கும், உள்நுழைவு தேவையில்லை. // @description:mr YouTube व्हिडिओ प्लेबॅक प्रगती आपोआप जतन करते आणि पुन्हा सुरू करते, लॉगिन आवश्यक नाही. // @description:zh-CN 自动保存并恢复 YouTube 视频的播放进度,无需登录。 // @description:zh-TW 自動儲存及繼續 YouTube 影片播放進度,無需登入。 // @description:zh-HK 自動儲存及繼續 YouTube 影片播放進度,無需登入。 // @description:ja YouTube の動画再生の進行状況を自動で保存・再開します。ログインは不要です。 // @description:ko YouTube 동영상 재생 진행 상황을 자동으로 저장하고 이어서 재생합니다. 로그인 불필요. // @description:th บันทึกและเล่นต่อความคืบหน้าของวิดีโอบน YouTube โดยอัตโนมัติ โดยไม่ต้องเข้าสู่ระบบ. // @description:vi Tự động lưu và tiếp tục tiến trình phát video trên YouTube mà không cần đăng nhập. // @description:id Menyimpan dan melanjutkan kemajuan pemutaran video di YouTube secara otomatis tanpa perlu login. // @description:ms Menyimpan dan menyambung semula kemajuan main balik video di YouTube secara automatik tanpa perlu log masuk. // @description:tl Awtomatikong ini-save at ipinagpapatuloy ang progreso ng video playback sa YouTube nang hindi nagla-log in. // @description:my YouTube ဗီဒီယိုဖလေ့ဘက် တိုးတက်မှုကို အလိုအလျောက် သိမ်းဆည်းပြီး ထပ်မံစတင်နိုင်သည်။ ဝင်ရောက်ရန် မလိုအပ်ပါ။ // @description:sw Hifadhi na endelea kwa kiotomatiki maendeleo ya uchezaji wa video kwenye YouTube bila kuingia. // @description:am በYouTube ላይ የቪዲዮ መጫወቻ እድገትን በራሱ ያስቀምጣል እና ያቀጥላል በመግባት ያስፈልጋል። // @description:ha Ajiye kuma ci gaba da ci gaban kallon bidiyo a YouTube ta atomatik ba tare da shiga ba. // @description:ur YouTube پر ویڈیوز کی پلے بیک کی پیش رفت کو خودکار طریقے سے محفوظ اور دوبارہ شروع کریں، لاگ ان کی ضرورت نہیں۔ // @description:ca Desa i reprèn automàticament el progrés de reproducció de vídeos a YouTube sense necessitat d'iniciar sessió. // @description:zu Igcina futhi uqhubeke ngokuzenzakalelayo nokuqhubeka kwevidiyo ku-YouTube ngaphandle kokungena. // @description:yue 自動儲存及繼續 YouTube 影片播放進度,無需登入。 // @description:es-419 Guarda y reanuda automáticamente el progreso de reproducción de videos en YouTube sin necesidad de iniciar sesión. // @homepage https://github.com/Alplox/Youtube-Playback-Plox // @supportURL https://github.com/Alplox/Youtube-Playback-Plox/issues // @version 0.0.9-15 // @author Alplox // @match https://www.youtube.com/* // @exclude https://www.youtube.com/live_chat* // @icon https://raw.githubusercontent.com/Alplox/StartpagePlox/refs/heads/main/assets/favicon/favicon.ico // @grant GM_getValue // @grant GM_setValue // @grant GM_deleteValue // @grant GM_listValues // @grant GM_registerMenuCommand // @grant GM_xmlhttpRequest // @grant GM_addElement // @grant GM_addStyle // @run-at document-end // @namespace youtube-playback-plox // @license MIT // @require https://update.greasyfork.icu/scripts/549881/1814457/YouTube%20Helper%20API.js // @downloadURL https://update.greasyfork.icu/scripts/553387/YouTube%20Playback%20Plox.user.js // @updateURL https://update.greasyfork.icu/scripts/553387/YouTube%20Playback%20Plox.meta.js // ==/UserScript== // ------------------------------------------ // MARK: 🔍 SISTEMA DE LOGGING // ------------------------------------------ (function () { 'use strict'; const L = { silent: 0, error: 1, warn: 2, info: 3, debug: 4 }; const level = L.silent; // Cambiar a 'debug' para ver todo, o 'warn'/'error' para menos const S = { debug: 'color:#6a9955;', info: 'color:#4FC1FF;', warn: 'color:#ce9178;font-weight:bold;', error: 'color:#f44747;font-weight:bold;' }; const noop = () => { }; const build = (t, l) => (level >= l || t === 'error') ? (c, ...a) => console[t](`%c[${c}]`, S[t], ...a) : noop; window.MyScriptLogger = { _errorLogs: [], log: (c, ...a) => { if (level >= L.debug) console.log(`%c[${c}]`, S.debug, ...a); }, debug: build('debug', L.debug), info: build('info', L.info), warn: (c, ...a) => { console.warn(`%c[${c}]`, S.warn, ...a); // window.MyScriptLogger._internalPushLog(c, a); }, error: (c, ...a) => { console.error(`%c[${c}]`, S.error, ...a); window.MyScriptLogger._internalPushLog(c, a); }, group: (label) => { if (level >= L.debug) console.group(`%c[${label}]`, S.debug); }, groupEnd: () => { if (level >= L.debug) console.groupEnd(); }, _internalPushLog: (c, a) => { const timestamp = new Date().toISOString(); const errorDetails = a.map(arg => { if (arg instanceof Error) return arg.stack || arg.message; if (typeof arg === 'object') { try { return JSON.stringify(arg, null, 2); } catch (e) { return '[Object (Unstringifiable)]'; } } return String(arg); }).join(' '); window.MyScriptLogger._errorLogs.push(`[${timestamp}] [${c}] ${errorDetails}`.trim()); if (window.MyScriptLogger._errorLogs.length > 50) window.MyScriptLogger._errorLogs.shift(); } }; // Global Error Trackers window.addEventListener('error', (e) => { const msg = (e.message || e.error?.message || '').toLowerCase(); if (msg.includes('resizeobserver loop') || msg.includes('undelivered notifications')) { return; } if (e.filename && e.filename.includes('youtube-playback-plox')) { window.MyScriptLogger.error('Global Error', e.error || e.message); } else if (!e.filename || e.filename === '') { window.MyScriptLogger.error('DOM Error', e.error || e.message); } }); window.addEventListener('unhandledrejection', (e) => { if (e.reason && (e.reason instanceof Error) && e.reason.stack && e.reason.stack.includes('youtube-playback-plox')) { window.MyScriptLogger.error('Unhandled Promise', e.reason); } else if (e.reason && e.reason.message && e.reason.message.includes('getCascadedVideoInfo')) { window.MyScriptLogger.error('Unhandled Promise', e.reason); } else if (e.reason && e.reason.stack === undefined) { window.MyScriptLogger.error('Unhandled Promise', e.reason); } }); })(); // Atajo para no tener que escribir window.MyScriptLogger cada vez const { log: logLog, info: logInfo, warn: logWarn, error: logError, group: logGroup, groupEnd: logGroupEnd } = window.MyScriptLogger; // --- INICIO CARGA LÓGICA PRINCIPAL DEL USERSCRIPT --- (() => { 'use strict'; const SCRIPT_VERSION = typeof GM_info !== 'undefined' ? GM_info.script.version : '0.0.9-15'; // ------------------------------------------ // MARK: 🛡️ Initialization Guard (SPA Safety) // ------------------------------------------ // Evita que el script se ejecute más de una vez en la misma página. window.__YPP__ = window.__YPP__ || {}; if (window.__YPP__?.status === 'initialized' && window.__YPP__?.version === SCRIPT_VERSION) { logLog('[YPP Initialization]', `Already initialized (v${SCRIPT_VERSION}), skipping bootstrap.`); return; } window.__YPP__.status = 'initialized'; window.__YPP__.version = SCRIPT_VERSION; window.__YPP__.destroy = () => { if (typeof cleanup === 'function') cleanup(false); window.__YPP__.status = 'destroyed'; logLog('[YPP Initialization]', 'Force destroyed.'); }; // NOTA: Nunca almacenar elementos DOM crudos (ej.