2.**Sidecar** (external) — `.srt`, `.vtt`, `.ass`, `.ssa`, `.sub` files placed next to the video on disk. Discovered automatically on library scan.
3.**Downloaded** — fetched at scan time (or via "Find subtitles" UI) by a subtitle provider plugin (OpenSubtitles, etc.). Saved as a sidecar when `SaveSubtitlesWithMedia=true`.
A user's `SubtitleMode` setting (per-user) decides what is auto-selected at playback:
-`None` — never load subtitles by default.
-`Default` — load only if marked `IsDefault` in the file.
-`Always` — always load if any track in `SubtitleLanguagePreference` exists.
-`Smart` — load only when audio language differs from the user's audio preference.
-`OnlyForced` — load only forced tracks.
The s8n user is set to **`Always` + preference `eng`** (see § 6).
---
## 2. Current Futurama state (verified 2026-05-08)
```
Library: TV Shows (Id 767bffe4f11c93ef34b805451a696a4e, path /media/tv)
Video: h264 1080p (the eng tag on the video stream is a mux artefact, not English audio)
Subs: 0 embedded, 0 sidecar — verified on episodes 1–5; assume same for all 44
```
Result: every episode needs subs from OpenSubtitles **or** sidecars dropped on disk. There is nothing to extract — `mkvextract`/`ffmpeg` would yield nothing.
---
## 3. OpenSubtitles plugin — what is installed, what is pending
### 3.1 Installed (done by automation 2026-05-08)
| Item | Value |
|---|---|
| Plugin | **Open Subtitles** v20.0.0.0 |
| GUID | `4b9ed42f-5185-48b5-9803-6ff2989014c4` |
| Status | `Active` (after `docker restart jellyfin`, ~5 s downtime) |
| Repo | Official `https://repo.jellyfin.org/files/plugin/manifest.json` (already configured) |
| API endpoint | `https://api.opensubtitles.com/api/v1` (REST, NOT the legacy XML-RPC at .org) |
| API key | **Embedded in the plugin binary** — user does NOT supply one |
### 3.2 Why v20 and not v24
| Plugin version | targetAbi | Compatible with 10.10.3? |
|---|---|---|
| v24, v23, v22, v21 | 10.11.x | **NO** — ABI too new, will not load |
| **v20** | **10.9.0.0** | **YES** — installed |
| v19 and older | 10.8.x | yes but lacks recent fixes |
When the server is upgraded to 10.11.x, switch to v24 via:
2. Sign up with the same email — the system will offer to import the .org account.
3. Reset password (mandatory; the .org password hash is incompatible).
User does NOT need to obtain an API key. The plugin embeds its own key (verified by reading `OpenSubtitlesPlugin.ApiKey` in `RequestHandler.cs` of v20). Free accounts get **20 downloads/day**; VIP accounts get more.
### 3.4 Pending — user supplies credentials
After signup at opensubtitles.com, save creds via API:
```bash
TOKEN=*redacted*
USER='your-opensubtitles-com-username'
PASS='your-opensubtitles-com-password'
# 1. Validate (returns 200 on success, 401 on bad creds)
Or via UI: `Dashboard → Plugins → Open Subtitles → Settings`.
A failed validate currently returns `{"Message":"Error, invalid username/password failed:5 remaining:5"}` HTTP 401 — the embedded API key is fine, only the user creds are missing.
---
## 4. Library + user configuration (already applied)
`POST /Library/VirtualFolders/LibraryOptions` was issued with:
```json
{
"Id": "767bffe4f11c93ef34b805451a696a4e",
"LibraryOptions": {
"SubtitleDownloadLanguages": ["eng"],
"RequirePerfectSubtitleMatch": false,
"SkipSubtitlesIfAudioTrackMatches": true,
"SkipSubtitlesIfEmbeddedSubtitlesPresent": false,
"SaveSubtitlesWithMedia": true,
"AllowEmbeddedSubtitles": "AllowAll"
}
}
```
Effect:
- **`SubtitleDownloadLanguages: ["eng"]`** — primary trigger. Any new scan or "Refresh metadata" will fetch English subs for items lacking them.
- **`RequirePerfectSubtitleMatch: false`** — accept good-match subs even when filename hashes don't line up (Polish-dub `Futurama.s01e01.pl.mkv` will not byte-match an English .srt anywhere on the planet).
- **`SkipSubtitlesIfAudioTrackMatches: true`** — never fetch a language already present as an audio track (no English audio here, so no effect; safe to leave on).
- **`SaveSubtitlesWithMedia: true`** — write `.eng.srt` next to the `.mkv` instead of caching in the metadata folder. Survives library wipes and is portable.
`MetadataRefreshMode=FullRefresh` triggers subtitle download for items missing matching language. This will take a few minutes and is rate-limited by the OpenSubtitles 20-downloads/day cap on free accounts. **44 episodes exceeds that** — plan for 3 days, or upgrade to VIP, or use sidecars (§ 7).
---
## 6. Per-user vs library default — who wins
| Setting | Lives in | Effect |
|---|---|---|
| `SubtitleDownloadLanguages` (library) | Library options | What languages are *fetched* and *saved to disk* |
| `SubtitleLanguagePreference` (user) | User config | Which existing track is *auto-selected at playback* |
| `SubtitleMode` (user) | User config | When to auto-display (`Always` / `Default` / `OnlyForced` / `Smart` / `None`) |
| `AudioLanguagePreference` (user) | User config | Which audio track is auto-selected |
A user's preferences are *display-time* only — they cannot trigger a download. A library's `SubtitleDownloadLanguages` is *scan-time* only — it does not affect what plays. You need both, and they should agree.
---
## 7. Sidecar subtitles — naming convention
If/when subs come from OpenSubtitles, Jellyfin saves them as sidecars (because `SaveSubtitlesWithMedia=true`). You can also drop your own. Filename pattern:
**Language codes:** Jellyfin accepts both ISO-639-1 (`en`, `pl`, `de`) and ISO-639-2/T (`eng`, `pol`, `deu`). Either works for filename matching — the parser canonicalises to 639-2 internally.
**Region tags** like `en-US`, `pt-BR` are accepted and shown to the user but treated as the bare language for matching.
# Then OCR with subtitleedit-cli or pgs2srt to convert to text srt.
```
Or with `mkvextract` (mkvtoolnix-cli):
```bash
mkvmerge -i input.mkv # lists tracks with IDs
mkvextract tracks input.mkv 2:input.en.srt
```
Jellyfin also has a built-in plugin **Subtitle Extract** (manifest GUID `cd893c24-b59e-4060-87b2-184070e1bf68`, latest v7.0.0.0 needs ABI 10.11.2.0 — wait until 10.11 upgrade). It extracts on the fly and caches in `metadata/Subtitles/`.
---
## 9. Auto-download settings cheatsheet
| Field | Where set | Recommended value | Why |
|---|---|---|---|
| `SubtitleDownloadLanguages` | Library options | `["eng"]` | Trigger downloads in English |
| `RequirePerfectSubtitleMatch` | Library options | `false` | Don't insist on hash-match for foreign-dub releases |
| `SkipSubtitlesIfEmbeddedSubtitlesPresent` | Library options | `false` | Allow override fetch even if embedded subs exist (e.g. if embedded are forced-only) |
| `SkipSubtitlesIfAudioTrackMatches` | Library options | `true` | Don't fetch English subs for English audio (no waste) |
| `SaveSubtitlesWithMedia` | Library options | `true` | Subs saved as sidecars on disk; portable; survives metadata wipe |
| `MaxResults` | (n/a in v20 plugin config) | — | The plugin returns the provider's full list; client picks |
| `IsAutomated` | (n/a, removed) | — | Older plugins had a flag; v20 always auto-fetches when a library scan finds an item missing the configured language |
---
## 10. Troubleshooting
| Symptom | Cause / fix |
|---|---|
| `RemoteSearch` returns `[]` for every episode | Creds missing / wrong (HTTP 401 in plugin logs). Re-validate via `ValidateLoginInfo`. |
| `429 Too Many Requests` in logs | Hit the 20/day quota on free account. Wait 24 h, upgrade to VIP, or fall back to sidecars. |
| Subs found but in wrong language | OpenSubtitles can mislabel — set `RequirePerfectSubtitleMatch: true` to filter, or pick manually via UI. |
| `.srt` on disk but Jellyfin doesn't show it | Filename language token doesn't match. Use `.en.srt` not `.english.srt`. Trigger library scan. |
| Subs show but client doesn't auto-display | User-side. Set `SubtitleMode: Always` and `SubtitleLanguagePreference: eng`. |
| Embedded subs preferred over downloaded | Expected — embedded come first in the priority order. Use the player's track switcher, or remux without subs. |
| `CredentialsInvalid: true` keeps reappearing | Plugin auto-flips this on a 401. Re-enter creds (likely changed on opensubtitles.com) and reset to `false`. |
| Plugin v24 install but stuck on `Restart` forever after upgrade | Server still on 10.10.x — v24 needs ABI 10.11. Reinstall v20. |
| Plugin **Open Subtitles v20.0.0.0** | Installed + Active |
| TV library `SubtitleDownloadLanguages` | `["eng"]` |
| TV library `RequirePerfectSubtitleMatch` | `false` |
| TV library `SaveSubtitlesWithMedia` | `true` |
| User `s8n``SubtitleMode` | `Always` |
| User `s8n``SubtitleLanguagePreference` | `eng` |
| User `s8n``AudioLanguagePreference` | `pol` |
| OpenSubtitles **credentials** | **PENDING — user signs up at <https://www.opensubtitles.com>** |
| Series refresh to fetch all 44 | **PENDING — after creds entered** |
When the user enters creds and runs the series refresh in § 5.2, expect ~20 episodes downloaded the first day (free quota), the rest over the next two days unless upgraded. Sidecar filenames will be `Futurama.s01eXX.pl.eng.srt` next to each `.mkv`.