134 lines
5.0 KiB
C#
134 lines
5.0 KiB
C#
using System;
|
|
using System.Linq;
|
|
using System.Net.Mime;
|
|
using MediaBrowser.Controller.Library;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
namespace JellyfinPlugin.Api
|
|
{
|
|
[ApiController]
|
|
[Route("BlackBarRemover")]
|
|
public class BlackBarController : ControllerBase
|
|
{
|
|
private readonly ILibraryManager _libraryManager;
|
|
private readonly ILogger<BlackBarController> _logger;
|
|
|
|
public BlackBarController(ILibraryManager libraryManager, ILogger<BlackBarController> logger)
|
|
{
|
|
_libraryManager = libraryManager;
|
|
_logger = logger;
|
|
}
|
|
|
|
[HttpGet("CropByPath")]
|
|
[Produces("text/plain")]
|
|
public ContentResult GetCropByPath([FromQuery] string path)
|
|
{
|
|
if (string.IsNullOrEmpty(path)) return Content(string.Empty, "text/plain");
|
|
|
|
var mode = Plugin.Instance!.Configuration.PlaybackMode;
|
|
if (mode == "Client") return Content(string.Empty, "text/plain");
|
|
|
|
var item = _libraryManager.RootFolder.GetRecursiveChildren().FirstOrDefault(x => x.Path == path);
|
|
|
|
if (item != null && item.ProviderIds != null && item.ProviderIds.TryGetValue("BlackBarCrop", out string? cropData))
|
|
{
|
|
return Content(cropData ?? string.Empty, "text/plain");
|
|
}
|
|
|
|
return Content(string.Empty, "text/plain");
|
|
}
|
|
|
|
[HttpGet("CropById")]
|
|
[Produces("text/plain")]
|
|
public ContentResult GetCropById([FromQuery] string itemId)
|
|
{
|
|
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 (Guid.TryParse(itemId, out Guid id))
|
|
{
|
|
var item = _libraryManager.GetItemById(id);
|
|
if (item != null && item.ProviderIds != null && item.ProviderIds.TryGetValue("BlackBarCrop", out string? cropData))
|
|
{
|
|
return Content(cropData ?? string.Empty, "text/plain");
|
|
}
|
|
}
|
|
|
|
return Content(string.Empty, "text/plain");
|
|
}
|
|
|
|
[HttpGet("ClientScript.js")]
|
|
[Produces("application/javascript")]
|
|
public ContentResult GetClientScript()
|
|
{
|
|
string js = @"
|
|
(function() {
|
|
console.log('Black Bar Remover: Script loaded');
|
|
let currentVideoElement = null;
|
|
|
|
function applyCrop(cropData) {
|
|
if (!currentVideoElement) return;
|
|
const parts = cropData.split(':');
|
|
if (parts.length === 4) {
|
|
const w = parseInt(parts[0]);
|
|
const h = parseInt(parts[1]);
|
|
const x = parseInt(parts[2]);
|
|
const y = parseInt(parts[3]);
|
|
|
|
const topPercent = (y / 1080) * 100;
|
|
const bottomPercent = ((1080 - (y + h)) / 1080) * 100;
|
|
const leftPercent = (x / 1920) * 100;
|
|
const rightPercent = ((1920 - (x + w)) / 1920) * 100;
|
|
|
|
currentVideoElement.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})`;
|
|
}
|
|
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;
|
|
}
|
|
}
|
|
|
|
setInterval(checkPlayback, 2000);
|
|
})();
|
|
";
|
|
return Content(js, "application/javascript");
|
|
}
|
|
}
|
|
}
|