MCPcopy Index your code
hub / github.com/McCloudS/subgen

github.com/McCloudS/subgen @main

Chat with this repo
repository ↗ · DeepWiki ↗ · + Follow
278 symbols 779 edges 13 files 67 documented · 24%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

Subgen

Donate

Updates:

7 Jun 2026: Fixed a bug where files containing only a forced embedded subtitle track were incorrectly treated as having full subtitle coverage and skipped. Forced tracks cover only a small fraction of dialogue (typically foreign-language inserts) and should not count as full coverage. Added IGNORE_FORCED_SUBTITLES (default True) to control this behaviour.

11 Apr 2026: Fixed subtitle timing on files with audio stream offsets (common in Amazon WEB-DL). Whisper ignores silence padding, causing subtitles to be early by the offset amount. Subgen now detects this via ffprobe and compensates automatically when the source video file is accessible. See Audio Start-Time Offset Fix for details.

27 Mar 2026: Potentially added ROCm support for AMD GPU/APUs. I don't have anything to test it, so a fair chance it doesn't work at all. I'm unsure if it will work with AMD APUs. Image is: mccloud/subgen:amd. It's pretty large right now at ~10gb. In theory, it should see your AMD card the same way it sees any other cuda device. Some light research shows ROCm only 'officially' supports higher end consumer cards and datacenter cards. HSA_OVERRIDE_GFX_VERSION can be set to 'trick' your old cards (and maybe APUs) to work, but you'll have to do your own research/googling.

17 Mar 2026: Added WEBHOOK_URL_COMPLETED. When a task finishes, Subgen will send a POST request with a JSON structure.

4 Mar 2026: Reformmated the readme and spend an hour with Gemini trying to format it and clean it up and it essentially only gave me icons for headers.

Feb 2026: Contributor helped cut the GPU container size in half. Added ASR_TIMEOUT as environment variable to timeout ASR endpoint transcriptions after X seconds.

31 Jan 2026: Added the ability to run the container 'rootless', accepts PUID and PGID as environment variables and should take user at a container level (Podman), let me know!.

13 Jan 2026: Probably fixed the runaway memory problems for CPU only. Added MODEL_CLEANUP_DELAY which will wait X seconds before purging the model to clear up (V)RAM. This mostly helps with Bazarr or when concurrent transcriptions is 1. Rewrote ASR (Bazarr) queuing so it should respect queing and follow concurrent transcriptions. Also fixed the error when too many Bazarr or ASR requests would start to fail.

26 Aug 2025: Renamed environment variables to make them slightly easier to understand. Currently maintains backwards compatibility. See https://github.com/McCloudS/subgen/pull/229

12 Aug 2025: Added distil-large-v3.5

7 Feb 2025: Fixed (V)RAM clearing, added PLEX_QUEUE_SEASON, other extraneous fixes or refactorting.

23 Dec 2025: Added PLEX_QUEUE_NEXT_EPISODE and PLEX_QUEUE_SERIES. Will automatically start generating subtitles for the next episode in your series, or queue the whole series.

4 Dec 2025: Added more ENV settings: DETECT_LANGUAGE_OFFSET, PREFERRED_AUDIO_LANGUAGES, SKIP_IF_AUDIO_TRACK_IS, ONLY_SKIP_IF_SUBGEN_SUBTITLE, SKIP_UNKNOWN_LANGUAGE, SKIP_IF_LANGUAGE_IS_NOT_SET_BUT_SUBTITLES_EXIST, SHOULD_WHISPER_DETECT_AUDIO_LANGUAGE

30 Nov 2024: Signifcant refactoring and handling by Muisje. Added language code class for more robustness and flexibility and ability to separate audio tracks to make sure you get the one you want. New ENV Variables: SUBTITLE_LANGUAGE_NAMING_TYPE, SKIP_IF_AUDIO_TRACK_IS, PREFERRED_AUDIO_LANGUAGE, SKIP_IF_TO_TRANSCRIBE_SUB_ALREADY_EXIST There will be some minor hiccups, so please identify them as we work through this major overhaul.

22 Nov 2024: Updated to support large-v3-turbo

30 Sept 2024: Removed webui

5 Sept 2024: Fixed Emby response to a test message/notification. Clarified Emby/Plex/Jellyfin instructions for paths.

14 Aug 2024: Cleaned up usage of kwargs across the board a bit. Added ability for /asr to encode or not, so you don't need to worry about what files/formats you upload.

3 Aug 2024: Added SUBGEN_KWARGS environment variable which allows you to override the model.transcribe with most options you'd like from whisper, faster-whisper, or stable-ts. This won't be exposed via the webui, it's best to set directly.

21 Apr 2024: Fixed queuing with thanks to https://github.com/xhzhu0628 @ https://github.com/McCloudS/subgen/pull/85. Bazarr intentionally doesn't follow CONCURRENT_TRANSCRIPTIONS because it needs a time sensitive response.

31 Mar 2024: Removed /subsync endpoint and general refactoring. Open an issue if you were using it!

24 Mar 2024: ~~Added a 'webui' to configure environment variables. You can use this instead of manually editing the script or using Environment Variables in your OS or Docker (if you want). The config will prioritize OS Env Variables, then the .env file, then the defaults. You can access it at http://subgen:9000/~~

23 Mar 2024: Added CUSTOM_REGROUP to try to 'clean up' subtitles a bit.

22 Mar 2024: Added LRC capability via see: LRC_FOR_AUDIO_FILES | True | Will generate LRC (instead of SRT) files for filetypes: '.mp3', '.flac', '.wav', '.alac', '.ape', '.ogg', '.wma', '.m4a', '.m4b', '.aac', '.aiff'

21 Mar 2024: Added a 'wizard' into the launcher that will help standalone users get common Bazarr variables configured. See below in Launcher section. Removed 'Transformers' as an option. While I usually don't like to remove features, I don't think anyone is using this and the results are wildly unpredictable and often cause out of memory errors. Added two new environment variables called USE_MODEL_PROMPT and CUSTOM_MODEL_PROMPT. If USE_MODEL_PROMPT is True it will use CUSTOM_MODEL_PROMPT if set, otherwise will default to using the pre-configured language pairings. These pre-configurated translations are geared towards fixing some audio that may not have punctionation. We can prompt it to try to force the use of punctuation during transcription.

19 Mar 2024: Added a MONITOR environment variable. Will 'watch' or 'monitor' your TRANSCRIBE_FOLDERS for changes and run on them. Useful if you just want to paste files into a folder and get subtitles.

6 Mar 2024: Added a /subsync endpoint that can attempt to align/synchronize subtitles to a file. Takes audio_file, subtitle_file, language (2 letter code), and outputs an srt.

5 Mar 2024: Cleaned up logging. Added timestamps option (if Debug = True, timestamps will print in logs).

4 Mar 2024: Updated Dockerfile CUDA to 12.2.2 (From CTranslate2). Added endpoint /status to return Subgen version. Can also use distil models now! See variables below!

29 Feb 2024: Changed default port to align with whisper-asr and deconflict other consumers of the previous port.

11 Feb 2024: Added a 'launcher.py' file for Docker to prevent huge image downloads. Now set UPDATE to True if you want pull the latest version, otherwise it will default to what was in the image on build. Docker builds will still be auto-built on any commit. If you don't want to use the auto-update function, no action is needed on your part and continue to update docker images as before. Fixed bug where detect-langauge could return an empty result. Reduced useless debug output that was spamming logs and defaulted DEBUG to True. Added APPEND, which will add a transcribed watermark at the end of a subtitle.

10 Feb 2024: Added some features from JaiZed's branch such as skipping if SDH subtitles are detected, functions updated to also be able to transcribe audio files, allow individual files to be manually transcribed, and a better implementation of forceLanguage. Added /batch endpoint (Thanks JaiZed). Allows you to navigate in a browser to http://subgen_ip:9000/docs and call the batch endpoint which can take a file or a folder to manually transcribe files. Added CLEAR_VRAM_ON_COMPLETE, HF_TRANSFORMERS, HF_BATCH_SIZE. Hugging Face Transformers boast '9x increase', but my limited testing shows it's comparable to faster-whisper or slightly slower. I also have an older 8gb GPU. Simplest way to persist HF Transformer models is to set "HF_HUB_CACHE" and set it to "/subgen/models" for Docker (assuming you have the matching volume).

8 Feb 2024: Added FORCE_DETECTED_LANGUAGE_TO to force a wrongly detected language. Fixed asr to actually use the language passed to it.

5 Feb 2024: General housekeeping, minor tweaks on the TRANSCRIBE_FOLDERS function.

28 Jan 2024: Fixed issue with ffmpeg python module not importing correctly. Removed separate GPU/CPU containers. Also removed the script from installing packages, which should help with odd updates I can't control (from other packages/modules). The image is a couple gigabytes larger, but allows easier maintenance.

19 Dec 2023: Added the ability for Plex and Jellyfin to automatically update metadata so the subtitles shows up properly on playback. (See https://github.com/McCloudS/subgen/pull/33 from Rikiar73574)

31 Oct 2023: Added Bazarr support via Whipser provider.

25 Oct 2023: Added Emby (IE http://192.168.1.111:9000/emby) support and TRANSCRIBE_FOLDERS, which will recurse through the provided folders and generate subtitles. It's geared towards attempting to transcribe existing media without using a webhook.

23 Oct 2023: There are now two docker images, ones for CPU (it's smaller): mccloud/subgen:latest, mccloud/subgen:cpu, the other is for cuda/GPU: mccloud/subgen:cuda. I also added Jellyfin support and considerable cleanup in the script. I also renamed the webhooks, so they will require new configuration/updates on your end. Instead of /webhook they are now /plex, /tautulli, and /jellyfin.

22 Oct 2023: The script should have backwards compability with previous envirionment settings, but just to be sure, look at the new options below. If you don't want to manually edit your environment variables, just edit the script manually. While I have added GPU support, I haven't tested it yet.

19 Oct 2023: And we're back! Uses faster-whisper and stable-ts. Shouldn't break anything from previous settings, but adds a couple new options that aren't documented at this point in time. As of now, this is not a docker image on dockerhub. The potential intent is to move this eventually to a pure python script, primarily to simplify my efforts. Quick and dirty to meet dependencies: pip or pip3 install flask requests stable-ts faster-whisper

This potentially has the ability to use CUDA/Nvidia GPU's, but I don't have one set up yet. Tesla T4 is in the mail!

2 Feb 2023: Added Tautulli webhooks back in. Didn't realize Plex webhooks was PlexPass only. See below for instructions to add it back in.

31 Jan 2023 : Rewrote the script substantially to remove Tautulli and fix some variable handling. For some reason my implementation requires the container to be in host mode. My Plex was giving "401 Unauthorized" when attempt to query from docker subnets during API calls. (Fixed now, it can be in bridge)


🎬 What is this?

Subgen transcribes your personal media to create subtitles (.srt or .lrc) from audio/video files. It can transcribe non-English languages to themselves, or translate foreign languages into English.

It is designed to integrate perfectly with Bazarr (as a Whisper Provider), or run via webhooks triggered directly by your Plex, Emby, Jellyfin, or Tautulli servers whenever media is added or played. Under the hood, it uses stable-ts and faster-whisper, fully supporting both CPU and Nvidia GPU (CUDA) transcoding.

🤔 Why?

Some shows just won't have subtitles available, or embedded H265 subtitles might be wildly out of sync. This gap-fills everything else by generating highly accurate subtitles locally on your own hardware.


⚡ Quick Start: Bazarr (The Bare Minimum)

If you just want to plug Subgen into Bazarr and get going, here is the absolute minimum you need to configure in your Subgen Docker container. No path mapping or media mounts are needed!

1. Set your Environment Variables in Subgen: * TRANSCRIBE_DEVICE: Set to cuda if you have an Nvidia GPU (highly recommended for speed), otherwise leave as cpu. * WHISPER_MODEL: Default is medium. Try large-v3-turbo if you have a GPU with 8GB+ VRAM for faster transcription. Note: large-v3-turbo only supports transcription — if you need translation (e.g. TRANSCRIBE_OR_TRANSLATE=translate), use large-v3 instead. * CONCURRENT_TRANSCRIPTIONS: Default is 2. Lower to 1 if you are running out of RAM/VRAM.

2. Configure Bazarr: * In Bazarr, go to Settings > Whisper Provider. * Select Whisper as the provider. * Set the Docker Endpoint to your Subgen IP and port: http://<your-ip>:9000 (Note: Do not use 127.0.0.1 if Bazarr is also in a Docker container). * Save! Subgen will now act as an invisible, self-hosted API for Bazarr's transcription requests.

3. Disable Auto-Sync for Subgen subtitles (important): Subgen already produces accurately timed subtitles. If you have Bazarr's Automatic Subtitles Audio Synchronization enabled, you must exclude whisperai from it — otherwise Bazarr will run ffsubsync on top of already-synced subtitles and degrade their quality. * In Bazarr, go to Settings > Subtitles > Audio Synchronization. * Under "Do not sync subtitles downloaded from those providers", add whisperai.


🔧 Audio Start-Time Offset Fix

Some media containers — particularly Amazon WEB-DL files — have an audio stream that starts later than the video stream (e.g., audio start_time of ~4 seconds). When Bazarr extracts audio from these files, it compensates by prepending silence via ffmpeg's adelay filter. However, Whisper's speech recognition completely ignores this digital silence, producing timestamps that are early by the

Core symbols most depended-on inside this repo

get
called by 73
subgen.py
put
called by 32
subgen.py
from_string
called by 32
language_code.py
convert_to_bool
called by 19
subgen.py
get_env_with_fallback
called by 17
subgen.py
should_skip_file
called by 15
subgen.py
to_iso_639_1
called by 12
language_code.py
to_name
called by 12
language_code.py

Shape

Method 144
Function 77
Class 45
Route 12

Languages

Python100%

Modules by API surface

subgen.py102 symbols
tests/test_language_code.py31 symbols
tests/test_helpers.py28 symbols
tests/test_endpoints.py26 symbols
tests/test_queue.py25 symbols
tests/test_skip_logic.py22 symbols
language_code.py14 symbols
tests/test_bug_fixes.py9 symbols
tests/test_integration.py8 symbols
tests/test_audio_tracks.py7 symbols
launcher.py6 symbols

For agents

$ claude mcp add subgen \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page