# Jellyfin Black Bar Remover Plugin A Jellyfin plugin that automatically detects and removes black bars (letterboxing/pillarboxing) from video files. ## Features - **Automated Scanning**: Hooks into the Jellyfin library scan (`ItemAdded` / `ItemUpdated`) to analyze videos in the background using FFmpeg keyframe skipping. - **Robust Detection**: Filters out brief format changes (like studio logos or dark transitions) to find the true "safe crop" bounding box for the entire video. - **Native Storage**: Saves detected crop parameters natively inside the Jellyfin SQLite database via `ProviderIds`. - **Dual Playback Modes**: - **Client-Side (CSS Clip)**: Automatically injects a JavaScript module into the Jellyfin Web UI. The script reads the crop data and uses CSS `clip-path` and `transform` to crop the video in the browser without any server-side transcoding overhead (Direct Play). - **Server-Side (FFmpeg Wrapper)**: Generates an `ffmpeg-wrapper.sh` script that can be used to inject the FFmpeg `-vf crop` filter during active transcoding. ## Requirements - Jellyfin Server **10.11** or **12.0+** (.NET 9 / .NET 10). - FFmpeg installed on the server. ## Tested Versions This plugin has been verified and tested on: - **Jellyfin 10.11.x** (.NET 9.0) - **Jellyfin 12.0 / 13.0 Unstable** (.NET 10.0) ## Installation ### Method 1: Jellyfin Repository (Recommended & Easiest) > [!TIP] > **Plugin Repository URL**: > ```text > https://gitea.labus.uk/karol/blackBarRemover/raw/branch/master/manifest.json > ``` 1. Open your Jellyfin Dashboard and navigate to **Dashboard** -> **Plugins** -> **Repositories** (`Repositories` tab). 2. Click the **`+`** icon to add a new repository. 3. Enter **`Black Bar Remover`** as the Repository Name. 4. Copy and paste the **Repository URL** above into the **Repository URL** field, then click **Save**. 5. Switch to the **Catalog** tab, find **Black Bar Remover** (under the *Playback* category), and click **Install**. 6. Restart your Jellyfin server. ### Method 2: Manual Installation from Releases 1. Go to the **Releases** tab on the Gitea repository page. 2. Download the latest `BlackBarRemover_vX.X.zip` file. 3. Extract the contents of the ZIP file into a new folder named `BlackBarRemover` inside your Jellyfin plugins directory (e.g., `/var/lib/jellyfin/plugins/BlackBarRemover/`). 4. Restart the Jellyfin server. ### Method 3: Building from Source 1. Clone this repository. 2. Ensure you have the **.NET 9.0 SDK** and/or **.NET 10.0 SDK** installed (the project multi-targets both `net9.0` and `net10.0`). 3. Build the plugin for all targets: ```bash dotnet build JellyfinPlugin/JellyfinPlugin.csproj -c Release ``` Or build for a specific target framework: ```bash # For Jellyfin 10.11 (.NET 9.0) dotnet build JellyfinPlugin/JellyfinPlugin.csproj -c Release -f net9.0 # For Jellyfin 12.0 / 13.0 Unstable (.NET 10.0) dotnet build JellyfinPlugin/JellyfinPlugin.csproj -c Release -f net10.0 ``` 4. Copy the compiled DLLs from `JellyfinPlugin/bin/Release/net9.0/` (for Jellyfin 10.11) or `JellyfinPlugin/bin/Release/net10.0/` (for Jellyfin 12.0+) into a new folder named `BlackBarRemover` inside your Jellyfin plugins directory (e.g., `/var/lib/jellyfin/plugins/BlackBarRemover/`). 5. Restart the Jellyfin server. ### Configuration & Initial Scan 1. Go to **Dashboard** -> **Plugins** -> **Black Bar Remover**. 2. Set your **Crop Detect Limit** (Default is `0.094`). If your web-dl rips have noisy black bars that are not being cropped, increase this value to `0.15` or `0.20`. 3. Set **Max Parallel Scans** (Default is `4`, Range `1 - 16`). Controls how many video files are scanned concurrently during library tasks to maximize multi-core CPU utilization. 4. Set **Client Subtitle Offset** (Default is `5.0 vh`, Range `0.0 - 25.0 vh`). Adjusts the vertical offset of subtitles when CSS crop is active in the Web player. 5. Select your preferred **Playback Mode**: - `Auto`: Lightweight CSS clipping for Web browser DirectPlay; FFmpeg transcoding for native apps. - `Client`: Uses CSS injection in the web player. - `Server`: Requires setting up the FFmpeg wrapper. 6. **Live Subtitle Adjustment during Playback**: While watching a video in Jellyfin Web with CSS crop enabled, you can press **`Alt + ArrowUp`** or **`Alt + ArrowDown`** to adjust the subtitle vertical position on the fly in real-time with on-screen feedback! 7. **Important for existing libraries**: The plugin automatically scans *new* files when they are added to Jellyfin. For your existing library, go to **Dashboard -> Scheduled Tasks** and run the **"Scan Missing Black Bars (Black Bar Remover)"** task manually. It will scan all existing movies and episodes in the background. ### Activating the Server-Side Wrapper (Automatic) If you select "Server" or "Both" mode, the plugin automatically generates a wrapper script and dynamically injects it into Jellyfin's `EncoderAppPath` configuration during startup. It takes over the transcoding process effortlessly. If it ever points to the wrong real FFmpeg, you can adjust it in the wrapper script. ### Activating the Client-Side CSS (Automatic) The plugin attempts to automatically inject its JavaScript into the Jellyfin Web `index.html` on startup. If it fails due to file permissions, you can manually activate it by adding the following line to **Dashboard** -> **General** -> **Custom CSS**: ```html ``` ## How it works When a video is scanned, a background process runs `ffmpeg -skip_frame nokey -i -vf cropdetect`. It collects all crops and ignores anomalies (appearing in < 5% of frames). The resulting bounding box is saved to the Jellyfin database under the `BlackBarCrop` provider ID. --- *Note: This plugin, including its logic, FFmpeg integrations, and documentation, was generated entirely with the assistance of an advanced AI agent (Google Antigravity / Gemini) during a pair-programming session.*