diff --git a/JellyfinPlugin/Api/BlackBarService.cs b/JellyfinPlugin/Api/BlackBarService.cs index c7f4c7a..367863b 100644 --- a/JellyfinPlugin/Api/BlackBarService.cs +++ b/JellyfinPlugin/Api/BlackBarService.cs @@ -41,12 +41,12 @@ namespace JellyfinPlugin.Api [HttpGet("CropById")] [Produces("text/plain")] - public ContentResult GetCropById([FromQuery] string itemId) + public ContentResult GetCropById([FromQuery] string itemId, [FromQuery] bool ignoreMode = false) { if (string.IsNullOrEmpty(itemId)) return Content(string.Empty, "text/plain"); var mode = Plugin.Instance!.Configuration.PlaybackMode; - if (mode == "Server") return Content(string.Empty, "text/plain"); + if (mode == "Server" && !ignoreMode) return Content(string.Empty, "text/plain"); if (Guid.TryParse(itemId, out Guid id)) { @@ -152,14 +152,82 @@ namespace JellyfinPlugin.Api }; } + function checkServerCrop(itemId) { + window._originalFetch('/BlackBarRemover/CropById?itemId=' + itemId + '&ignoreMode=true') + .then(r => r.text()) + .then(crop => { + if (crop) { + window._isServerCropping = true; + } else { + window._isServerCropping = false; + } + }) + .catch(e => { window._isServerCropping = false; }); + } + + const playbackInfoObserver = new MutationObserver((mutations) => { + if (!window._isServerCropping) return; + + for (let m of mutations) { + if (m.type === 'characterData') { + if (m.target.nodeValue) { + const text = m.target.nodeValue.trim(); + if (text === ""The video's resolution is not supported"" || + text === ""VideoResolutionNotSupported"" || + text.includes(""rozdzielczość nie jest obsługiwana"") || + text === ""Rozdzielczość wideo nie jest obsługiwana"") { + m.target.nodeValue = ""Black Bar Removal (Server Mode)""; + } + } + } else if (m.type === 'childList') { + m.addedNodes.forEach(node => { + if (node.nodeType === Node.ELEMENT_NODE) { + const textContent = node.textContent || """"; + if (textContent.includes(""The video's resolution is not supported"") || + textContent.includes(""VideoResolutionNotSupported"") || + textContent.includes(""rozdzielczość"")) { + const walker = document.createTreeWalker(node, NodeFilter.SHOW_TEXT, null, false); + let textNode; + while (textNode = walker.nextNode()) { + if (textNode.nodeValue) { + const t = textNode.nodeValue.trim(); + if (t === ""The video's resolution is not supported"" || + t === ""VideoResolutionNotSupported"" || + t.includes(""rozdzielczość nie jest obsługiwana"") || + t === ""Rozdzielczość wideo nie jest obsługiwana"") { + textNode.nodeValue = ""Black Bar Removal (Server Mode)""; + } + } + } + } + } else if (node.nodeType === Node.TEXT_NODE) { + if (node.nodeValue) { + const t = node.nodeValue.trim(); + if (t === ""The video's resolution is not supported"" || + t === ""VideoResolutionNotSupported"" || + t.includes(""rozdzielczość nie jest obsługiwana"") || + t === ""Rozdzielczość wideo nie jest obsługiwana"") { + node.nodeValue = ""Black Bar Removal (Server Mode)""; + } + } + } + }); + } + } + }); + + playbackInfoObserver.observe(document.body, { childList: true, subtree: true, characterData: true }); + 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); + checkServerCrop(currentItemId); } else if (!video) { currentItemId = null; + window._isServerCropping = false; } }, 2000); })();