From 5f8674fae41ef2fb60e323592293a85a72fba720 Mon Sep 17 00:00:00 2001 From: Karol Labus Date: Thu, 17 Sep 2026 16:38:23 +0200 Subject: [PATCH] Fix Client Mode execution and network interception logic --- JellyfinPlugin/Api/BlackBarService.cs | 99 ++++++++++++++++++--------- 1 file changed, 68 insertions(+), 31 deletions(-) diff --git a/JellyfinPlugin/Api/BlackBarService.cs b/JellyfinPlugin/Api/BlackBarService.cs index a5cc838..c7f4c7a 100644 --- a/JellyfinPlugin/Api/BlackBarService.cs +++ b/JellyfinPlugin/Api/BlackBarService.cs @@ -67,10 +67,12 @@ namespace JellyfinPlugin.Api string js = @" (function() { console.log('Black Bar Remover: Script loaded'); - let currentVideoElement = null; + let currentItemId = null; + let interceptedItemId = null; function applyCrop(cropData) { - if (!currentVideoElement) return; + const video = document.querySelector('video'); + if (!video) return; const parts = cropData.split(':'); if (parts.length === 4) { const w = parseInt(parts[0]); @@ -83,48 +85,83 @@ namespace JellyfinPlugin.Api const leftPercent = (x / 1920) * 100; const rightPercent = ((1920 - (x + w)) / 1920) * 100; - currentVideoElement.style.clipPath = `inset(${topPercent}% ${rightPercent}% ${bottomPercent}% ${leftPercent}%)`; + video.style.clipPath = `inset(${topPercent}% ${rightPercent}% ${bottomPercent}% ${leftPercent}%)`; const scaleY = 1 / (1 - (topPercent + bottomPercent)/100); const scaleX = 1 / (1 - (leftPercent + rightPercent)/100); const scale = Math.max(scaleY, scaleX); if (scale > 1.01) { - currentVideoElement.style.transform = `scale(${scale})`; + video.style.transform = `scale(${scale})`; } console.log('Black Bar Remover: Applied crop', cropData, 'scale', scale); } } - function checkPlayback() { - const video = document.querySelector('video'); - if (video && video !== currentVideoElement) { - console.log('Black Bar Remover: Found new video element'); - currentVideoElement = video; - const match = window.location.href.match(/[?&](id|itemId)=([^&#]+)/i); - const itemId = match ? match[2] : null; - - console.log('Black Bar Remover: Parsed itemId from URL:', itemId, 'URL was:', window.location.href); - - if (itemId) { - console.log('Black Bar Remover: Fetching crop data for item', itemId); - fetch('/BlackBarRemover/CropById?itemId=' + itemId) - .then(r => r.text()) - .then(crop => { - console.log('Black Bar Remover: Received crop data:', crop); - if (crop) applyCrop(crop); - }) - .catch(e => console.error('Black Bar Remover: API fetch error:', e)); - } else { - console.log('Black Bar Remover: Could not find itemId in URL to fetch crop data.'); - } - } else if (!video && currentVideoElement) { - console.log('Black Bar Remover: Video element removed'); - currentVideoElement = null; - } + function fetchCrop(itemId) { + console.log('Black Bar Remover: Fetching crop data for item', itemId); + window._originalFetch('/BlackBarRemover/CropById?itemId=' + itemId) + .then(r => r.text()) + .then(crop => { + console.log('Black Bar Remover: Received crop data:', crop); + if (crop) { + setTimeout(() => applyCrop(crop), 500); + setTimeout(() => applyCrop(crop), 2000); + } + }) + .catch(e => console.error('Black Bar Remover: API fetch error:', e)); } - setInterval(checkPlayback, 2000); + if (!window._originalFetch) { + window._originalFetch = window.fetch; + window.fetch = async function(...args) { + const url = typeof args[0] === 'string' ? args[0] : (args[0] && args[0].url); + if (url) { + const match = url.match(/\/Items\/([a-f0-9]{32}|[a-f0-9\-]{36})/i); + if (match) { + const id = match[1]; + if (id && id !== interceptedItemId) { + interceptedItemId = id; + console.log('Black Bar Remover: Intercepted itemId from fetch:', id); + } + } + } + return window._originalFetch.apply(this, args); + }; + } + + if (!window._originalXHR) { + window._originalXHR = window.XMLHttpRequest; + window.XMLHttpRequest = function() { + const xhr = new window._originalXHR(); + const originalOpen = xhr.open; + xhr.open = function(method, url, ...rest) { + if (url && typeof url === 'string') { + const match = url.match(/\/Items\/([a-f0-9]{32}|[a-f0-9\-]{36})/i); + if (match) { + const id = match[1]; + if (id && id !== interceptedItemId) { + interceptedItemId = id; + console.log('Black Bar Remover: Intercepted itemId from XHR:', id); + } + } + } + return originalOpen.apply(this, [method, url, ...rest]); + }; + return xhr; + }; + } + + setInterval(() => { + const video = document.querySelector('video'); + if (video && interceptedItemId && interceptedItemId !== currentItemId) { + currentItemId = interceptedItemId; + console.log('Black Bar Remover: Video element found for intercepted item:', currentItemId); + fetchCrop(currentItemId); + } else if (!video) { + currentItemId = null; + } + }, 2000); })(); "; return Content(js, "application/javascript");