// ==UserScript==
// @name YouTubeAdSolutions
// @name:ar YouTubeAdSolutions
// @name:be YouTubeAdSolutions
// @name:bg YouTubeAdSolutions
// @name:ckb YouTubeAdSolutions
// @name:cs YouTubeAdSolutions
// @name:da YouTubeAdSolutions
// @name:de YouTubeAdSolutions
// @name:el YouTubeAdSolutions
// @name:en YouTubeAdSolutions
// @name:eo YouTubeAdSolutions
// @name:es YouTubeAdSolutions
// @name:es-419 YouTubeAdSolutions
// @name:fi YouTubeAdSolutions
// @name:fr YouTubeAdSolutions
// @name:fr-CA YouTubeAdSolutions
// @name:he YouTubeAdSolutions
// @name:hr YouTubeAdSolutions
// @name:hu YouTubeAdSolutions
// @name:id YouTubeAdSolutions
// @name:it YouTubeAdSolutions
// @name:ja YouTubeAdSolutions
// @name:ka YouTubeAdSolutions
// @name:ko YouTubeAdSolutions
// @name:mr YouTubeAdSolutions
// @name:nb YouTubeAdSolutions
// @name:nl YouTubeAdSolutions
// @name:pl YouTubeAdSolutions
// @name:pt-BR YouTubeAdSolutions
// @name:ro YouTubeAdSolutions
// @name:ru YouTubeAdSolutions
// @name:sk YouTubeAdSolutions
// @name:sr YouTubeAdSolutions
// @name:sv YouTubeAdSolutions
// @name:th YouTubeAdSolutions
// @name:tr YouTubeAdSolutions
// @name:uk YouTubeAdSolutions
// @name:ug YouTubeAdSolutions
// @name:vi YouTubeAdSolutions
// @name:zh-CN YouTubeAdSolutions
// @name:zh-TW YouTubeAdSolutions
// @description Premium-Logo, Downloader, Audio-Features, Skip-Highlight, Picture-in-Picture, Miniplayer, Speed-Control & Shorts Volume Slider.
// @description:ar شعار بريميوم، أداة تنزيل، ميزات الصوت، تخطي التمييز، صورة داخل صورة، مشغل مصغر، التحكم بالسرعة ومنزلق صوت Shorts.
// @description:be Прэміум-лагатып, загрузнік, аўдыя-функцыі, прапуск падсветкі, малюнак у малюнку, міні-плэер, кантроль хуткасці і рэгулятар гучнасці Shorts.
// @description:bg Premium лого, изтегляне, аудио функции, пропускане на акценти, картина в картината, мини плейър, контрол на скоростта и плъзгач за силата на Shorts.
// @description:ckb لۆگۆی پرێمیوم، داگرتن، تایبەتمەندیی دەنگ، تێپەڕاندنی دیاریکردن، وێنە لە ناو وێنەدا، مینی پلەیەر، کۆنترۆڵی خێرایی و سلایدەری دەنگی Shorts.
// @description:cs Prémiové logo, stahování, zvukové funkce, přeskočení zvýraznění, obraz v obraze, minipřehrávač, ovládání rychlosti a posuvník hlasitosti Shorts.
// @description:da Premium-logo, downloader, lydfunktioner, spring markeringer over, billede-i-billede, miniafspiller, hastighedskontrol og lydstyrkeskyder til Shorts.
// @description:de Premium-Logo, Downloader, Audio-Funktionen, Skip-Highlight, Picture-in-Picture, Miniplayer, Geschwindigkeitskontrolle & Lautstärkeregler für Shorts.
// @description:el Λογότυπο Premium, λήψη, λειτουργίες ήχου, παράλειψη επισήμανσης, εικόνα σε εικόνα, mini player, έλεγχος ταχύτητας και ρυθμιστικό έντασης Shorts.
// @description:en Premium logo, downloader, audio features, skip highlight, picture-in-picture, miniplayer, speed control & Shorts volume slider.
// @description:eo Premium-emblemo, elŝutilo, sonaj funkcioj, preterpasi emfazon, bildo-en-bildo, mini-ludilo, rapideca kontrolo kaj glitilo de Shorts-laŭteco.
// @description:es Logotipo Premium, descargador, funciones de audio, omitir resaltado, imagen en imagen, minirreproductor, control de velocidad y control de volumen de Shorts.
// @description:es-419 Logotipo Premium, descargador, funciones de audio, omitir resaltados, imagen en imagen, minirreproductor, control de velocidad y control de volumen de Shorts.
// @description:fi Premium-logo, latausohjelma, ääniominaisuudet, korostusten ohitus, kuva kuvassa, minisoitin, nopeudensäätö ja Shorts-äänenvoimakkuussäädin.
// @description:fr Logo Premium, téléchargeur, fonctions audio, saut de surbrillance, image dans l’image, mini-lecteur, contrôle de vitesse et curseur de volume Shorts.
// @description:fr-CA Logo Premium, téléchargeur, fonctions audio, saut de surbrillance, image dans l’image, mini-lecteur, contrôle de vitesse et curseur de volume Shorts.
// @description:he לוגו פרימיום, הורדה, תכונות שמע, דילוג על הדגשות, תמונה בתוך תמונה, נגן מוקטן, שליטת מהירות ומחוון עוצמת קול ל-Shorts.
// @description:hr Premium logo, preuzimanje, audio funkcije, preskakanje isticanja, slika u slici, mini player, kontrola brzine i klizač glasnoće za Shorts.
// @description:hu Prémium logó, letöltő, hangfunkciók, kiemelések kihagyása, kép a képben, mini lejátszó, sebességszabályzás és Shorts hangerőcsúszka.
// @description:id Logo Premium, pengunduh, fitur audio, lewati sorotan, gambar dalam gambar, pemutar mini, kontrol kecepatan dan penggeser volume Shorts.
// @description:it Logo Premium, downloader, funzioni audio, salta evidenziazioni, picture-in-picture, mini player, controllo velocità e cursore volume Shorts.
// @description:ja プレミアムロゴ、ダウンローダー、音声機能、ハイライトのスキップ、ピクチャーインピクチャー、ミニプレーヤー、速度調整とShorts音量スライダー。
// @description:ka პრემიუმ ლოგო, ჩამოტვირთვა, აუდიო ფუნქციები, გამოკვეთების გამოტოვება, სურათი სურათში, მინი დამკვრელი, სიჩქარის კონტროლი და Shorts ხმის რეგულატორი.
// @description:ko 프리미엄 로고, 다운로드, 오디오 기능, 하이라이트 건너뛰기, 화면 속 화면, 미니 플레이어, 속도 조절 및 Shorts 볼륨 슬라이더.
// @description:mr प्रीमियम लोगो, डाउनलोडर, ऑडिओ वैशिष्ट्ये, हायलाइट वगळा, पिक्चर-इन-पिक्चर, मिनी प्लेअर, गती नियंत्रण आणि Shorts व्हॉल्यूम स्लायडर.
// @description:nb Premium-logo, nedlasting, lydfunksjoner, hopp over høydepunkter, bilde-i-bilde, minispiller, hastighetskontroll og volumskyveknapp for Shorts.
// @description:nl Premium-logo, downloader, audiofuncties, markeringen overslaan, picture-in-picture, minispeler, snelheidsregeling en volumeschuif voor Shorts.
// @description:pl Logo Premium, pobieranie, funkcje audio, pomijanie wyróżnień, obraz w obrazie, mini odtwarzacz, kontrola prędkości i suwak głośności Shorts.
// @description:pt-BR Logotipo Premium, downloader, recursos de áudio, pular destaques, picture-in-picture, mini player, controle de velocidade e controle de volume do Shorts.
// @description:ro Logo Premium, descărcare, funcții audio, sărire evidențieri, imagine în imagine, mini player, control viteză și glisor volum Shorts.
// @description:ru Премиум-логотип, загрузчик, аудиофункции, пропуск выделений, картинка в картинке, мини-плеер, контроль скорости и регулятор громкости Shorts.
// @description:sk Prémiové logo, sťahovanie, zvukové funkcie, preskočenie zvýraznení, obraz v obraze, mini prehrávač, ovládanie rýchlosti a posuvník hlasitosti Shorts.
// @description:sr Premium logo, preuzimanje, audio funkcije, preskakanje isticanja, slika u slici, mini plejer, kontrola brzine i klizač jačine zvuka za Shorts.
// @description:sv Premium-logotyp, nedladdning, ljudfunktioner, hoppa över markeringar, bild-i-bild, minispelare, hastighetskontroll och volymreglage för Shorts.
// @description:th โลโก้พรีเมียม, ดาวน์โหลด, ฟีเจอร์เสียง, ข้ามไฮไลต์, ภาพซ้อนภาพ, มินิเพลเยอร์, ควบคุมความเร็ว และตัวปรับเสียง Shorts
// @description:tr Premium logo, indirici, ses özellikleri, vurguları atla, resim içinde resim, mini oynatıcı, hız kontrolü ve Shorts ses kaydırıcısı.
// @description:uk Преміум-логотип, завантажувач, аудіофункції, пропуск виділень, зображення в зображенні, мініплеєр, контроль швидкості та регулятор гучності Shorts.
// @description:ug Premium لوگو، چۈشۈرگۈچ، ئاۋاز ئىقتىدارلىرى، يورۇتۇشنى ئۆتكۈزۈش، رەسىم ئىچىدە رەسىم، كىچىك قويغۇچ، سۈرئەت كونترول ۋە Shorts ئاۋاز سىيرىغۇچى.
// @description:vi Logo Premium, trình tải xuống, tính năng âm thanh, bỏ qua nổi bật, hình trong hình, trình phát mini, điều khiển tốc độ và thanh âm lượng Shorts.
// @description:zh-CN 高级徽标、下载器、音频功能、跳过高亮、画中画、迷你播放器、速度控制和 Shorts 音量滑块。
// @description:zh-TW 高級標誌、下載器、音訊功能、跳過重點、子母畫面、迷你播放器、速度控制與 Shorts 音量滑桿。
// @namespace http://tampermonkey.net/
// @version 2.2.1
// @author Pascal
// @match https://www.youtube.com/*
// @grant none
// @icon https://www.youtube.com/s/desktop/ee47b5e0/img/logos/favicon_144x144.png
// @run-at document-start
// @license MIT
// @downloadURL none
// ==/UserScript==
(function() {
'use strict';
let audioCtx, source, gainNode, bassFilter;
let isAudioInited = false;
let isAdActive = false;
const tripleControlClass = 'custom-audio-control';
// --- 0. ANTI-BLOCK-ENFORCEMENT ---
function removeEnforcementMessage() {
const enforcement = document.querySelector('ytd-enforcement-message-view-model');
if (enforcement) {
enforcement.remove();
const video = document.querySelector('video');
if (video && video.paused) video.play();
console.log("YouTube Sperr-Dialog entfernt.");
}
const overlay = document.querySelector('tp-yt-iron-overlay-backdrop');
if (overlay) { overlay.remove(); }
}
// --- 1. TRUSTED TYPES BYPASS ---
if (window.trustedTypes && trustedTypes.createPolicy) {
if (!trustedTypes.defaultPolicy) {
try {
const passThroughFn = (x) => x;
trustedTypes.createPolicy('default', {
createHTML: passThroughFn, createScriptURL: passThroughFn, createScript: passThroughFn,
});
} catch (e) {}
}
}
// --- 2. CSS ANPASSUNGEN (Global, Shorts & Settings-Menü) ---
const style = document.createElement('style');
style.innerHTML = `
ytd-masthead, #masthead-container { z-index: 50000 !important; }
#search-form, yt-searchbox { z-index: 60000 !important; position: relative !important; }
.ytp-pip-btn svg, #custom-miniplayer-button svg { fill: white !important; }
/* SHORTS SLIDER STYLING */
.custom-shorts-slider {
position: fixed;
right: 85px;
bottom: 50%;
transform: rotate(-90deg) translateX(50%);
transform-origin: right center;
width: 600px;
height: 8px;
accent-color: #ff0000;
z-index: 999999;
cursor: pointer;
opacity: 0;
transition: opacity 0.3s, visibility 0.3s;
visibility: hidden;
filter: drop-shadow(0px 0px 4px rgba(0,0,0,0.6));
}
body[is-shorts] .custom-shorts-slider {
opacity: 0.5;
visibility: visible;
}
body[is-shorts] .custom-shorts-slider:hover {
opacity: 1;
}
/* NEU: SETTINGS DROPDOWN ANIMATION & DESIGN */
#custom-settings-dropdown {
position: absolute;
background: #282828;
border-radius: 12px;
padding: 18px;
box-shadow: 0 12px 32px rgba(0,0,0,0.7);
z-index: 2147483647; /* Damit es wirklich über allem liegt */
width: 260px;
transform-origin: top right;
transition: transform 0.2s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.2s ease-out;
opacity: 0;
transform: scale(0.9) translateY(-10px);
visibility: hidden;
border: 1px solid rgba(255,255,255,0.1);
font-family: "Roboto", Arial, sans-serif;
pointer-events: none;
}
#custom-settings-dropdown.open {
opacity: 1;
transform: scale(1) translateY(0);
visibility: visible;
pointer-events: auto;
}
`;
document.head.appendChild(style);
// --- KONFIGURATION ---
let config = {
pipKey: localStorage.getItem('custom-pip-key') || 'p'
};
// --- 3. AUDIO LOGIK ---
function initAudio() {
const video = document.querySelector('video');
if (!video || isAudioInited) return;
try {
audioCtx = new (window.AudioContext || window.webkitAudioContext)();
source = audioCtx.createMediaElementSource(video);
gainNode = audioCtx.createGain();
bassFilter = audioCtx.createBiquadFilter();
bassFilter.type = "lowshelf";
bassFilter.frequency.value = 150;
source.connect(bassFilter);
bassFilter.connect(gainNode);
gainNode.connect(audioCtx.destination);
isAudioInited = true;
} catch (e) { console.warn("Audio Fehler:", e); }
}
function createControlPair(color, title) {
const $container = document.createElement('span');
$container.className = tripleControlClass;
$container.style.cssText = 'display: inline-flex; align-items: center; height: 100%; vertical-align: middle; margin-right: 8px;';
const $btn = document.createElement('button');
$btn.className = 'ytp-button';
$btn.title = title;
$btn.innerHTML = ``;
$btn.style.cssText = 'display: inline-flex; align-items: center; justify-content: center; min-width: 36px; height: 100%; cursor: pointer; background: none; border: none;';
const $slider = document.createElement('input');
$slider.type = 'range';
$slider.style.cssText = `display: none; width: 8vw; accent-color: ${color}; margin: 0 5px; cursor: pointer;`;
const $label = document.createElement('span');
$label.style.cssText = `display: none; color: ${color}; font-size: 11px; font-weight: bold; min-width: 30px; font-family: Roboto;`;
$btn.onclick = (e) => {
e.preventDefault();
const show = ($slider.style.display === 'none');
$slider.style.display = $label.style.display = show ? 'inline-block' : 'none';
};
$container.append($btn, $slider, $label);
return { $container, $slider, $label };
}
// --- 4. PiP LOGIK ---
async function togglePiP() {
const video = document.querySelector('video');
if (!video) return;
try {
if (document.pictureInPictureElement) { await document.exitPictureInPicture(); }
else { await video.requestPictureInPicture(); }
} catch (err) {}
}
// --- 5. PREMIUM LOGO ---
const PREMIUM_SVG_CONTENT = `
`;
function applyPremiumLogo() {
const logoSelectors = [
'ytd-topbar-logo-renderer #logo svg',
'ytd-guide-renderer #logo svg',
'ytd-logo svg',
'svg#yt-ringo2-svg_yt5',
'svg#yt-ringo2-svg_yt4'
];
logoSelectors.forEach(selector => {
const elements = document.querySelectorAll(selector);
elements.forEach(svg => {
if (svg && svg.getAttribute('data-is-premium') !== 'true') {
svg.setAttribute('width', '101');
svg.setAttribute('viewBox', '0 0 101 20');
svg.setAttribute('data-is-premium', 'true');
svg.innerHTML = PREMIUM_SVG_CONTENT;
}
});
});
}
// --- 6. SKIP-BUTTON HIGHLIGHT ---
function highlightSkip() {
const btn = document.querySelector('.ytp-skip-ad-button, .ytp-ad-skip-button');
if (btn && !btn.getAttribute('data-hl')) {
btn.setAttribute('data-hl', 'true');
btn.style.border = "3px solid #ff00ff";
btn.style.boxShadow = "0 0 15px #ff00ff";
btn.style.borderRadius = "4px";
}
}
// --- 7. DOWNLOADER ---
function initializDownload() {
const rightControls = document.querySelector('.ytp-right-controls');
if (!rightControls || document.getElementById('dwnldBtnPlayer')) return;
const dwnldBtn = document.createElement('button');
dwnldBtn.id = 'dwnldBtnPlayer';
dwnldBtn.className = 'ytp-button';
dwnldBtn.setAttribute('title', 'Download');
dwnldBtn.style.cssText = `display: inline-flex; align-items: center; justify-content: center; vertical-align: middle; width: 60px;`;
dwnldBtn.innerHTML = ``;
let menu = document.getElementById('dwnldMenuGlobal');
if (!menu) {
menu = document.createElement('div');
menu.id = 'dwnldMenuGlobal';
document.body.appendChild(menu);
}
menu.style.cssText = `display: none; position: fixed; background: rgba(28, 28, 28, 0.98); border-radius: 12px; min-width: 200px; box-shadow: 0 8px 32px rgba(0,0,0,0.8); z-index: 2147483647; padding: 8px 0; border: 1px solid rgba(255,255,255,0.15); font-family: 'Roboto', sans-serif; backdrop-filter: blur(12px);`;
dwnldBtn.addEventListener('click', (e) => {
e.preventDefault(); e.stopPropagation();
const rect = dwnldBtn.getBoundingClientRect();
const currentId = new URLSearchParams(window.location.search).get('v');
const sources = [
{ name: '🎞️ MP3 / MP4 (Y2Mate)', url: 'https://evdfrance.fr/convert/?id=' + currentId },
{ name: '🎶 MP3 (YTMP3)', url: 'https://ytmp3.as/#' + currentId + '/mp3' },
{ name: '🚀 4K Video (Loader)', url: 'https://loader.to/api/card/?url=https://www.youtube.com/watch?v=' + currentId },
{ name: '🟢 MP4 (SaveFrom)', url: 'https://ssyoutube.com/watch?v=' + currentId },
{ name: '✂️ DVR / Edit (Dirpy)', url: 'https://dirpy.com/studio?url=https://www.youtube.com/watch?v=' + currentId },
{ name: '📺 Multi-Format (noTube)', url: 'https://notube.net/convert/de?url=https://www.youtube.com/watch?v=' + currentId },
{ name: '🛡️ Cobalt (No Ads)', url: 'https://cobalt.tools/' }
];
menu.innerHTML = "";
sources.forEach(src => {
const item = document.createElement('a');
item.href = src.url; item.target = "_blank"; item.innerText = src.name;
item.style.cssText = "display: block; padding: 12px 20px; color: white; text-decoration: none; font-size: 14px;";
item.addEventListener('click', () => { menu.style.display = 'none'; });
item.onmouseover = () => item.style.backgroundColor = "rgba(255,255,255,0.1)";
item.onmouseout = () => item.style.backgroundColor = "transparent";
menu.appendChild(item);
});
menu.style.display = 'block';
const menuRect = menu.getBoundingClientRect();
menu.style.left = (rect.left + (rect.width / 2) - (menuRect.width / 2)) + 'px';
menu.style.top = (rect.top - menuRect.height - 15) + 'px';
const close = (ev) => { if (!dwnldBtn.contains(ev.target) && !menu.contains(ev.target)) { menu.style.display = 'none'; window.removeEventListener('mousedown', close); } };
setTimeout(() => window.addEventListener('mousedown', close), 1);
}, true);
const pipBtn = document.querySelector('.ytp-pip-btn') || document.querySelector('.ytp-miniplayer-button');
if (pipBtn) { rightControls.insertBefore(dwnldBtn, pipBtn); } else { rightControls.prepend(dwnldBtn); }
}
// --- 8. SETUP INTERFACE ---
function setupInterface() {
const rightControls = document.querySelector('.ytp-right-controls');
const timeDisp = document.querySelector('.ytp-time-display');
const videoPlayer = document.getElementById('movie_player');
if (timeDisp && !document.querySelector('.' + tripleControlClass)) {
const savedVol = sessionStorage.getItem('custom-player-volume') ?? 0.948;
if (videoPlayer && videoPlayer.setVolume) videoPlayer.setVolume((savedVol**2)*100);
const vol = createControlPair('#FF0000', 'Volume');
vol.$slider.min = '0'; vol.$slider.max = '1'; vol.$slider.step = '0.01';
vol.$slider.value = savedVol;
vol.$label.textContent = Math.round((savedVol**2)*100) + "%";
vol.$slider.oninput = () => {
if (videoPlayer && videoPlayer.setVolume) videoPlayer.setVolume((vol.$slider.value**2)*100);
vol.$label.textContent = Math.round((vol.$slider.value**2)*100) + "%";
sessionStorage.setItem('custom-player-volume', vol.$slider.value);
};
const savedBoost = sessionStorage.getItem('custom-player-boost') ?? 1;
const boost = createControlPair('#FFFF00', 'Booster');
boost.$slider.min = '1'; boost.$slider.max = '10'; boost.$slider.step = '0.1';
boost.$slider.value = savedBoost;
boost.$label.textContent = savedBoost + "x";
boost.$slider.oninput = () => {
initAudio();
if(gainNode) gainNode.gain.value = boost.$slider.value;
boost.$label.textContent = boost.$slider.value + "x";
sessionStorage.setItem('custom-player-boost', boost.$slider.value);
};
const savedBass = sessionStorage.getItem('custom-player-bass') ?? 0;
const bass = createControlPair('#FFA500', 'Bass');
bass.$slider.min = '0'; bass.$slider.max = '30'; bass.$slider.step = '1';
bass.$slider.value = savedBass;
bass.$label.textContent = savedBass + "dB";
bass.$slider.oninput = () => {
initAudio();
if(bassFilter) bassFilter.gain.value = bass.$slider.value;
bass.$label.textContent = bass.$slider.value + "dB";
sessionStorage.setItem('custom-player-bass', bass.$slider.value);
};
timeDisp.after(bass.$container);
timeDisp.after(boost.$container);
timeDisp.after(vol.$container);
}
if (rightControls && !document.querySelector('.ytp-pip-btn')) {
const pipBtn = document.createElement('button');
pipBtn.className = 'ytp-button ytp-pip-btn';
pipBtn.title = 'Picture-in-Picture (p)';
pipBtn.style.cssText = 'display: inline-flex; align-items: center; justify-content: center;';
pipBtn.innerHTML = ``;
pipBtn.onclick = (e) => { e.preventDefault(); togglePiP(); };
rightControls.prepend(pipBtn);
}
if (rightControls && !document.getElementById('custom-miniplayer-button')) {
const miniBtn = document.createElement('button');
miniBtn.id = 'custom-miniplayer-button';
miniBtn.className = 'ytp-button';
miniBtn.title = 'Miniplayer (i)';
miniBtn.style.cssText = 'display: inline-flex; align-items: center; justify-content: center;';
miniBtn.innerHTML = ``;
miniBtn.onclick = (e) => { e.preventDefault(); document.dispatchEvent(new KeyboardEvent('keydown', { key: 'i', keyCode: 73, bubbles: true })); };
rightControls.appendChild(miniBtn);
}
}
// --- 9. SPEED CONTROLLER ---
let manualSpeed = 1.0;
function setupSpeedInterface() {
const actionsMenu = document.querySelector('#actions-inner #menu ytd-menu-renderer #top-level-buttons-computed');
const video = document.querySelector('video');
if (!actionsMenu || !video || document.getElementById('premium-speed-control')) return;
const control = document.createElement('div');
control.id = 'premium-speed-control';
control.className = 'premium-speed-logic top-level-buttons style-scope ytd-menu-renderer';
control.innerHTML = `
${video.playbackRate}x
`;
const btnDown = control.querySelector('#speed-down-btn');
const btnUp = control.querySelector('#speed-up-btn');
const display = control.querySelector('#premium-speed-display');
const updateSpeed = (delta) => {
manualSpeed = Math.round((video.playbackRate + delta) * 100) / 100;
manualSpeed = Math.max(0.25, Math.min(10, manualSpeed));
video.playbackRate = manualSpeed;
display.textContent = `${manualSpeed}x`;
};
btnDown.onclick = (e) => { e.stopPropagation(); updateSpeed(-0.25); };
btnUp.onclick = (e) => { e.stopPropagation(); updateSpeed(0.25); };
video.addEventListener('ratechange', () => {
if (!isAdActive && video.playbackRate !== manualSpeed) { video.playbackRate = manualSpeed; display.textContent = `${manualSpeed}x`; }
});
actionsMenu.appendChild(control);
}
// --- 10. HANDLE ADS ---
function handleAds() {
const video = document.querySelector('video');
const ad = document.querySelector('.ad-showing, .ad-interrupting, .ytp-ad-player-overlay');
const speedDisplay = document.querySelector('#premium-speed-display');
if (video && ad) {
isAdActive = true;
if (!video.muted) { video.muted = true; video.volume = 0; }
if (video.playbackRate !== 2.0) { video.playbackRate = 2.0; }
if (speedDisplay && speedDisplay.textContent !== "2x") { speedDisplay.textContent = "2x"; }
} else if (video && isAdActive) {
isAdActive = false; video.muted = false;
const savedVol = sessionStorage.getItem('custom-player-volume') || 0.8;
video.volume = savedVol;
video.playbackRate = manualSpeed;
if (speedDisplay) speedDisplay.textContent = manualSpeed + "x";
}
}
// --- 10-b. PRESTIGE AD-REMOVER (Feed & Companion Ads) ---
function setupAdRemover() {
// Trusted Types Bypass (verhindert YouTube-Sperren bei Script-Eingriffen)
if (window.trustedTypes && trustedTypes.createPolicy && !trustedTypes.defaultPolicy) {
try {
const passThroughFn = (x) => x;
trustedTypes.createPolicy('default', {
createHTML: passThroughFn,
createScriptURL: passThroughFn,
createScript: passThroughFn,
});
} catch (e) {}
}
const cleanAds = () => {
// A) Badge-Suche (Entfernt Video-Ads im Feed)
const badges = document.querySelectorAll('badge-shape.yt-badge-shape--ad');
badges.forEach(badge => {
const adContainer = badge.closest('yt-lockup-view-model, ytd-rich-item-renderer, ytd-ad-slot-renderer, ytd-player-legacy-desktop-watch-ads-renderer');
if (adContainer) adContainer.remove();
});
// B) Selektoren-Suche (Banner, Masthead & Sidebar Ads)
const adSelectors = [
'#player-ads',
'ytd-player-legacy-desktop-watch-ads-renderer',
'#masthead-ad',
'ytd-display-ad-renderer',
'ytd-companion-slot-renderer',
'ytd-promoted-sparkles-web-renderer', // Zusätzliche Banner
'#rendering-content.ytd-fake-update-renderer' // Fake-Update Ads
];
adSelectors.forEach(s => document.querySelectorAll(s).forEach(el => el.remove()));
};
// Der Observer sorgt dafür, dass Ads auch beim Scrollen sofort verschwinden
const observer = new MutationObserver(() => cleanAds());
if (document.body) {
observer.observe(document.body, { childList: true, subtree: true });
cleanAds();
}
}
// --- 11. SHORTS VOLUME SLIDER ---
function setupShortsUI() {
// Sicherheits-Check: Falls body noch nicht existiert oder der Slider bereits da ist, abbrechen.
if (!document.body || document.querySelector('.custom-shorts-slider')) return;
const savedVol = sessionStorage.getItem('custom-player-volume') || 0.8;
const $slider = document.createElement('input');
$slider.className = 'custom-shorts-slider';
$slider.type = 'range'; $slider.min = '0'; $slider.max = '1'; $slider.step = '0.01';
$slider.value = savedVol;
const updateAllShorts = (val) => {
document.querySelectorAll('video').forEach(v => {
if (window.location.href.includes('/shorts/')) { v.volume = val; v.muted = (val == 0); }
});
};
$slider.oninput = () => updateAllShorts($slider.value);
$slider.onchange = () => sessionStorage.setItem('custom-player-volume', $slider.value);
// Sicherstellen, dass wir an den Body anhängen
document.body.appendChild($slider);
window.removeEventListener('yt-navigate-finish', checkShortsStatus); // Dubletten vermeiden
window.addEventListener('yt-navigate-finish', checkShortsStatus);
checkShortsStatus();
}
function checkShortsStatus() {
if (window.location.href.includes('/shorts/')) {
document.body.setAttribute('is-shorts', '');
const v = document.querySelector('video');
if (v) v.volume = sessionStorage.getItem('custom-player-volume') || 0.8;
} else { document.body.removeAttribute('is-shorts'); }
}
// --- 12. ANTI-PAUSE-DIALOG LOGIK ---
function autoConfirmVideoPaused() {
const confirmBtn = document.querySelector('yt-confirm-dialog-renderer #confirm-button button');
if (confirmBtn) {
confirmBtn.click();
console.log("%c[Premium] 'Video angehalten'-Dialog automatisch bestätigt.", "color: #00ffff");
const video = document.querySelector('video');
if (video && video.paused) { video.play(); }
}
}
// --- 13: SETTINGS ZAHNRAD ---
function addSettingsGear() {
const buttonContainer = document.querySelector('#top-level-buttons-computed');
if (buttonContainer && !document.querySelector('#mein-custom-settings-gear')) {
const gearButton = document.createElement('button');
gearButton.id = 'mein-custom-settings-gear';
gearButton.className = 'yt-spec-button-shape-next yt-spec-button-shape-next--tonal yt-spec-button-shape-next--mono yt-spec-button-shape-next--size-m yt-spec-button-shape-next--icon-button';
gearButton.style.marginLeft = '8px';
gearButton.title = 'Script Settings';
gearButton.innerHTML = `
`;
gearButton.onclick = (e) => {
e.preventDefault();
e.stopPropagation();
toggleSettingsMenu(gearButton);
};
buttonContainer.appendChild(gearButton);
}
}
// --- 14. SLIDE-OUT SETTINGS MENU (ENGLISH) ---
function toggleSettingsMenu(anchor) {
let menu = document.getElementById('custom-settings-dropdown');
if (!menu) {
menu = document.createElement('div');
menu.id = 'custom-settings-dropdown';
document.body.appendChild(menu);
}
const isOpen = menu.classList.contains('open');
if (isOpen) {
menu.classList.remove('open');
} else {
menu.innerHTML = `
Script Settings
PREMIUM
`;
const rect = anchor.getBoundingClientRect();
menu.style.top = (rect.bottom + window.scrollY + 12) + 'px';
menu.style.left = (rect.left + window.scrollX - 210) + 'px';
const input = menu.querySelector('#new-pip-key');
// Auto-Replace Logic
input.onkeydown = (e) => {
if (e.key.length === 1) {
input.value = e.key.toLowerCase();
e.preventDefault();
}
};
setTimeout(() => {
menu.classList.add('open');
input.focus();
input.select();
}, 10);
// Save
document.getElementById('save-settings-btn').onclick = () => {
const val = input.value.toLowerCase();
if (val && val.length === 1) {
config.pipKey = val;
localStorage.setItem('custom-pip-key', val);
menu.classList.remove('open');
console.log("%c[Premium] Settings saved!", "color: #3ea6ff");
}
};
// Reset
document.getElementById('reset-settings-btn').onclick = () => {
config.pipKey = 'p';
localStorage.setItem('custom-pip-key', 'p');
menu.classList.remove('open');
console.log("%c[Premium] Reset to default", "color: #ff4d4d");
};
const closeHandler = (ev) => {
if (!menu.contains(ev.target) && !anchor.contains(ev.target)) {
menu.classList.remove('open');
window.removeEventListener('mousedown', closeHandler);
}
};
window.addEventListener('mousedown', closeHandler);
}
}
// --- 15. DYNAMISCHE SHORTCUTS ---
document.addEventListener('keydown', (e) => {
// Ignorieren, wenn Nutzer schreibt ODER das Einstellungs-Modal offen ist
if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA' || e.target.isContentEditable) return;
// PiP Shortcut
if (e.key.toLowerCase() === config.pipKey) {
e.preventDefault();
if (typeof togglePiP === "function") togglePiP();
}
// Shift + P öffnet das neue Menü
if (e.shiftKey && e.key.toLowerCase() === 'p') {
e.preventDefault();
openHotkeySettings();
}
}, { capture: true });
// --- NAVIGATION & INITIALISIERUNG ---
const runAllSetups = () => {
setupInterface();
initializDownload();
setupSpeedInterface();
setupShortsUI();
applyPremiumLogo();
removeEnforcementMessage();
};
window.addEventListener('yt-navigate-finish', runAllSetups);
// --- INTERVALLE (ÜBERWACHUNG & AUTO-REACTION) ---
setInterval(handleAds, 200);
setInterval(setupAdRemover, 1500);
setInterval(addSettingsGear, 1500);
setInterval(autoConfirmVideoPaused, 1000);
setInterval(removeEnforcementMessage, 1000);
setInterval(applyPremiumLogo, 1500);
setInterval(highlightSkip, 1000);
setInterval(() => {
if (!document.getElementById('dwnldBtnPlayer')) initializDownload();
if (!document.querySelector('.' + tripleControlClass)) setupInterface();
if (!document.getElementById('premium-speed-control')) setupSpeedInterface();
}, 2000);
runAllSetups();
})();