// ==UserScript== // @name YouTube Toolkit+: NewPipe button + H264 ≤30FPS + YouTube Adblock // @version 1.0 // @description Floating NewPipe intent button (incl. Shorts), forces H.264 ≤30FPS, hides ad overlays, auto-skips & jumps YouTube ads mobile. // @author jc // @namespace https://viayoo.com/ // @match *://*.youtube.com/* // @match *://*.youtube-nocookie.com/* // @match *://*.youtubekids.com/* // @match https://m.youtube.com/* // @exclude *://www.youtube.com/*/music* // @exclude *://music.youtube.com/* // @run-at document-start // @grant none // @icon https://tenor.com/mIOhyqVCMa1.gif // @downloadURL none // ==/UserScript== /* ── 1. H.264 + FPS limiter (h264ify clone) ─────────────────────────────────── */ (function() { const BLOCK_HIGH_FPS = true; const DISALLOWED_TYPES_REGEX = /webm|vp8|vp9|av01/i; const FRAME_RATE_REGEX = /framerate=(\d+)/; const ms = window.MediaSource; if (!ms) return; const orig = ms.isTypeSupported.bind(ms); ms.isTypeSupported = (type) => { if (typeof type !== 'string') return false; if (DISALLOWED_TYPES_REGEX.test(type)) return false; const m = FRAME_RATE_REGEX.exec(type); if (BLOCK_HIGH_FPS && m && +m[1] > 30) return false; return orig(type); }; })(); /* ── 2. Ad-skip & overlay blocker (undetected, desktop + mobile) ───────────── */ (function() { 'use strict'; // 2A. Selectors & CSS for both desktop & mobile const SKIP_BUTTON_SELECTORS = [ 'button.ytp-ad-skip-button', 'button.ytp-ad-skip-button-modern', 'paper-button.ytp-ad-skip-button' // mobile Polymer button ]; const OVERLAY_CSS = [ '.ytp-ad-overlay.ytp-overlay-loading', // in-video desktop overlays '.ytp-featured-product', // featured product promos 'ytd-ad-preview-slot-renderer', // mobile ad preview 'ytm-compact-ad' // mobile compact ads ]; // Inject overlay-hiding CSS const style = document.createElement('style'); style.textContent = OVERLAY_CSS.join(',') + ' { display: none !important; }'; document.head.appendChild(style); // Click “Skip Ad” if present function clickSkip() { for (const sel of SKIP_BUTTON_SELECTORS) { const btn = document.querySelector(sel); if (btn) { btn.click(); return true; } } return false; } // Jump to video end if unskippable function jumpAd() { const v = document.querySelector('video'); if (v && isFinite(v.duration)) v.currentTime = v.duration; } // Observe player class changes function setupObserver(playerEl) { new MutationObserver(() => { if (playerEl.classList.contains('ad-showing')) { if (!clickSkip()) jumpAd(); } }).observe(playerEl, { attributes: true, attributeFilter: ['class'] }); } // Desktop player const desktopPlayer = document.getElementById('movie_player'); if (desktopPlayer) setupObserver(desktopPlayer); // Mobile player (Polymer element) const mobilePlayer = document.querySelector('ytm-player, ytd-player'); if (mobilePlayer) setupObserver(mobilePlayer); // Fallback periodic check setInterval(() => { if (document.querySelector('.ad-showing') || document.querySelector('video.ad-active')) { if (!clickSkip()) jumpAd(); } }, 1000); })(); /* ── 3. Floating NewPipe Button (incl. Shorts) ─────────────────────────────── */ (function() { 'use strict'; function buildIntent(id) { return `intent://www.youtube.com/watch?v=${id}#Intent;scheme=https;package=org.schabi.newpipe;end`; } function getVideoId() { try { const u = new URL(location.href); if (u.searchParams.has('v')) return u.searchParams.get('v'); const m = location.pathname.match(/\/shorts\/([^\/?&]+)/); return m ? m[1] : null; } catch { return null; } } function makeButton() { const btn = document.createElement('div'); btn.id = 'np-float-btn'; btn.textContent = '⬇️'; Object.assign(btn.style, { position: 'fixed', bottom: '80px', right: '16px', width: '48px', height: '48px', lineHeight:'48px', textAlign:'center', fontSize: '24px', backgroundColor: 'rgba(200,200,200,0.3)', color: '#000', borderRadius: '50%', zIndex: 999999, cursor: 'pointer', opacity: '0.7', transition:'opacity 0.2s' }); btn.addEventListener('mouseenter', ()=>{ btn.style.opacity='1'; }); btn.addEventListener('mouseleave', ()=>{ btn.style.opacity='0.7'; }); btn.addEventListener('click', ()=>{ const id = getVideoId(); if (!id) return alert('No video ID found.'); window.location.href = buildIntent(id); }); document.body.appendChild(btn); } function init() { if (document.body) { makeButton(); } else { new MutationObserver((_, obs)=>{ if (document.body) { obs.disconnect(); makeButton(); } }).observe(document.documentElement, { childList:true }); } } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })();