Token 76858153...f8b1 was committed across 9 docs + 1 snapshot RESTORE.md and exposed via the brief public window of this repo. Replaced with `<JELLYFIN_API_TOKEN>` placeholder. WARNING: this commit only redacts HEAD — the token remains in git history. Anyone who cloned during the public window has the full value. Treat the old token as compromised and rotate at Jellyfin Dashboard > API Keys. Original value backed up to private s8n/secrets/ARRFLIX/.
42 KiB
05 — File & Folder Structure Rules (arrflix.s8n.ru)
Last updated: 2026-05-08
Server: Jellyfin 10.10.3 on nullstone, container jellyfin
Library root inside container: /media
Library root on host: /home/user/media
This document is the authoritative ruleset for laying media out on disk so Jellyfin scrapes it correctly the first time, every time. Cross-linked to:
01-artwork-and-images.md— image scrapers and on-disk override files02-metadata-and-titles.md— filename parsing,RemoteSearch/Apply, the lock-the-series flow03-subtitles.md— sidecar.srt/.assnaming and the OpenSubtitles plugin04-theming-and-users.md— multi-user policies and library access
Sources of truth (check these BEFORE this doc — they update):
- https://jellyfin.org/docs/general/server/media/movies/
- https://jellyfin.org/docs/general/server/media/shows/
- https://jellyfin.org/docs/general/server/media/music/
- https://jellyfin.org/docs/general/server/media/books/
- https://jellyfin.org/docs/general/server/libraries/
- https://jellyfin.org/docs/general/server/metadata/nfo/
- Source:
Emby.Naming.dllships in the container at/jellyfin/Emby.Naming.dll. Rules below match the Emby.Naming regex chain referenced by the docs. CollectionType.cs(master):unknown, movies, tvshows, music, musicvideos, trailers, homevideos, boxsets, books, photos, livetv, playlists, folders(enum int values 0–12).
0. Top-level rules (apply to everything)
These are non-negotiable. Most "Jellyfin won't match my file" tickets are caused by violating one of these:
- One library = one
CollectionType. Never mix Movies and TV in the same library. Mixed libraries technically exist (mixed) but lose half the scrapers and most edge-case parsing — do not use. - One folder per item. A movie lives in its own folder. A series lives in its own folder. A music album lives in its own folder. Loose files in the library root will scrape, but extras / NFO / artwork sidecars cannot attach to a loose file.
- Forbidden filename characters:
< > : " / \ | ? *These are illegal on Windows and Jellyfin's parser refuses to canonicalise them. Use--for:, drop quotes entirely. - No accents/non-ASCII in folder names unless you are sure the underlying
filesystem (
ext4here) and SMB/NFS clients all support UTF-8. We're onext4+ LAN-only HTTP, so accents are safe — but avoid them where the ASCII title is well-known (e.g.Amelie (2001)notAmélie (2001)). - Always include the year for movies/series whose title is not unique:
The Office (2005)vsThe Office (2001)(UK),It (2017)vsIt (1990). Year goes in parentheses immediately after the title with a single space. - Year is parsed only when in
( )—Movie 2005.mkvdoes NOT bind 2005 as the year, it becomes part of the title.Movie (2005).mkvdoes. - Provider-ID overrides win over filename guessing. If a title is
ambiguous or the scraper repeatedly picks the wrong show, embed the ID:
Series Name (2023) [tmdbid-12345]/. Doc 02 covers theRemoteSearch/Applypath for fixing this after-the-fact via API. SeriesName/Season XX/SeriesName SXXEYY.extis the canonical TV layout. Anything flatter or deeper has corner cases. Stick to it.- Dots, dashes, underscores, and spaces are interchangeable between tokens
for the parser.
Futurama.s01e01.pl.mkvparses identically toFuturama - S01E01 - pl.mkv. Pick one and be consistent inside a library. - Refresh after a rename. Renaming a file on disk does NOT auto-refresh
the existing Jellyfin item — it creates a new "missing" record. Either
rename BEFORE first scan, or
POST /Library/Refreshafter.
1. Movies
1.1 Folder structure
/media/movies/
├── Blade Runner (1982)/
│ └── Blade Runner (1982).mkv
├── Blade Runner 2049 (2017)/
│ ├── Blade Runner 2049 (2017) - 2160p.mkv
│ ├── Blade Runner 2049 (2017) - 1080p.mkv
│ └── Blade Runner 2049 (2017) - Theatrical.mkv
├── Dune (1984)/
│ └── Dune (1984) [imdbid-tt0087182].mkv
├── Dune (2021)/
│ └── Dune (2021).mkv
└── Lord of the Rings - Fellowship (2001)/
├── Lord of the Rings - Fellowship (2001) - cd1.mkv
└── Lord of the Rings - Fellowship (2001) - cd2.mkv
One folder per movie. Folder name = movie name.
1.2 Filename pattern
- Pattern:
^<Title> \((?<year>\d{4})\)( \[(imdbid|tmdbid|tvdbid)-[^\]]+\])?( - <Label>)?\.<ext>$ - Title is whatever you put — but it must byte-for-byte match the parent folder name when using multi-version naming.
- Year in
(YYYY)is technically optional but required for this deploy. - Provider-ID block
[imdbid-ttNNNNNNN]/[tmdbid-NNNN]/[tvdbid-NNNN]is optional; use it when the title is ambiguous or scraper picks wrong. - Label for multi-version movies:
- <free text>or- [<free text>]. Resolution labels ending inpori(2160p,1080p,720i) sort descending by resolution; everything else sorts alphabetically.
Examples that WORK
Blade Runner (1982).mkv
Blade Runner (1982) [imdbid-tt0083658].mkv
Blade Runner 2049 (2017) - 2160p.mkv
Blade Runner 2049 (2017) - Directors Cut.mkv
Blade Runner 2049 (2017) - [Extended].mkv
Lord of the Rings - Fellowship (2001) - cd1.mkv
Lord of the Rings - Fellowship (2001) - part 1.mkv
Lord of the Rings - Fellowship (2001).part.1.mkv
Examples that BREAK
Blade Runner.1982.mkv ← year not in parens; title becomes "Blade Runner 1982"
Blade.Runner.(1982).mkv ← parses but folder/file mismatch will void multi-version
BR (1982).mkv ← title too cryptic, scraper guesses wrong
Blade Runner (1982) - Directors Cut.mkv ← in folder "BladeRunner1982" → mismatch
LOTR: Fellowship (2001).mkv ← `:` is illegal
Movies/Blade Runner (1982).mkv ← no per-movie folder; extras/NFO can't attach
1.3 Multi-disc / multi-part rips
Use part separators cd|dvd|part|pt|disc|disk followed by a number, optionally
preceded by space/./-/_:
Lord of the Rings - Fellowship (2001) - cd1.mkv
Lord of the Rings - Fellowship (2001) - cd2.mkv
Limitation (from upstream docs, verbatim): "This does not work with multiple versions or merging." → if you have a 2-disc 2160p AND a 2-disc 1080p of the same movie, you must remux into single files; the parser cannot encode both axes.
1.4 Foreign-language audio dubs
Jellyfin matches on the original title (English/release-language) regardless
of audio. Polish-dubbed Futurama would be:
/media/movies/Futurama - Bender's Big Score (2007)/
└── Futurama - Bender's Big Score (2007).mkv ← Polish audio inside
Do NOT put .pl in the filename — the audio language tag is a track-level
attribute (read from the mkv stream), not a filename token. If you must
distinguish two language rips of the same film, use the multi-version pattern:
Movie (2020) - PL Dub.mkv
Movie (2020) - Original.mkv
1.5 Year disambiguation
When two films share a title, year alone is what the scraper uses. If both are 1980, fall back to provider IDs:
/media/movies/Bad Movie (1980) [imdbid-tt0080000]/
/media/movies/Bad Movie (1980) [imdbid-tt0080001]/
1.6 Scrapers
- Primary: TheMovieDb (TMDb) — bundled, on by default.
- Fallback / cross-reference: OMDb (IMDb-backed; ships with Jellyfin core).
- Image-only: TheMovieDb covers most posters/backdrops. Add the
Fanart.tv plugin if you need clearart, disc, logo overrides — see
01-artwork-and-images.md§ 4. - Trailers: TheMovieDb attaches YouTube trailer links automatically; the AniList / TheTVDB plugins do not apply here.
1.7 Edge cases
VIDEO_TS/BDMVrips are supported but lose multi-version, multi-part, and external subtitles. Avoid for new rips; remux to mkv.- Pre-release / unofficial cuts (Snyder Cut, Final Cut Pro, etc.) → use the multi-version label, not a separate folder.
- Movies that became series (e.g. Fargo) — the original film goes in
/media/movies/, the show in/media/tv/. Provider IDs prevent cross-match. - Anime films that are part of a TV show (One Piece: Stampede) — see § 3.6.
2. TV shows
2.1 Folder structure (canonical)
/media/tv/
├── Futurama (1999)/
│ ├── Season 00/ ← specials live here
│ │ └── Futurama (1999) S00E01 - Christmas Special.mkv
│ ├── Season 01/
│ │ ├── Futurama (1999) S01E01.mkv
│ │ ├── Futurama (1999) S01E02.mkv
│ │ └── Futurama (1999) S01E03-E04.mkv ← multi-episode file
│ ├── Season 02/
│ └── tvshow.nfo ← optional, doc § 11
└── The Office (2005)/
└── Season 01/
└── The Office (2005) S01E01.mkv
Per-season folders are mandatory for this deploy. Flat (no season folders) parses but loses the per-season-poster override path (§ 10) and breaks for shows >2 seasons.
2.2 Filename pattern
- Pattern:
^.*?[Ss](?<season>\d{1,2})[Ee](?<episode>\d{1,3})(-[Ee]?(?<end>\d{1,3}))?(\s.*)?\.<ext>$ - Season + episode tokens recognised by the parser (case-insensitive, dots and dashes equivalent to spaces — verified in doc 02 § 2):
| Pattern | Example | Result |
|---|---|---|
S##E## |
Futurama S01E01.mkv |
s1e1 |
s##e## |
Futurama.s01e01.pl.mkv |
s1e1 (current Futurama) |
Season ## Episode ## |
Futurama Season 1 Episode 1.mkv |
s1e1 |
##x## |
Futurama 1x01.mkv |
s1e1 |
S##E##-E## |
Futurama S01E01-E02.mkv |
one file, eps 1+2 |
S##E## - S##E## |
Futurama S01E01 - S01E02.mkv |
multi range |
Series name comes from the parent folder (preferred) or the filename
prefix before the S##E## token. If both are present, folder wins.
Examples that WORK
Futurama (1999)/Season 01/Futurama (1999) S01E01.mkv
Futurama (1999)/Season 01/Futurama.s01e01.pl.mkv
Futurama (1999)/Season 01/Futurama 1x01 Space Pilot 3000.mkv
Futurama (1999)/Season 01/Futurama S01E01-E02.mkv
Futurama (1999)/Season 00/Futurama (1999) S00E01 - Bender Big Score.mkv
Examples that BREAK
Futurama/Futurama-Pilot.mkv ← no S##E## token, ungrabbable as episode
Futurama/Season1/... ← "Season1" — needs space: "Season 1" or "Season 01"
Futurama/Specials/... ← "Specials" doesn't match; use "Season 00"
Futurama/Season 01/01.mkv ← parser sees no season+episode token, only "01"
Futurama/S01/Futurama_S01E01.mkv ← top-level folder is "S01", series name = "S01"
Futurama (1999) S01E01.mkv ← in /media/tv/ root; no series folder
2.3 Specials (Season 0)
- Folder:
Season 00(zero-padded).Specials/,Season 0/,Season Specials/do not match the parser. - Filename:
Series (year) S00E01 - Title.mkv—S00is required; without it the file falls into "no season" and is ignored. - For specials that should appear inside a regular season (e.g. between S03E04
and S03E05), use NFO
<airsbefore_season>/<airsafter_season>/<airsbefore_episode>tags AND enable "Display specials within their series" in library settings.
2.4 Multi-episode files
Two formats accepted:
Futurama (1999) S01E01-E02.mkv ← preferred
Futurama (1999) S01E01 - S01E02.mkv ← also accepted
Both tag the file as "stacked" — Jellyfin shows it as one entry on the episode list and plays the entire file when either episode is clicked.
2.5 Date-based / daily shows
The official docs do not define a date-based pattern as of 2026-05. The practical workaround for daily shows (talk shows, news) is to fake them into seasonal numbering by year:
The Daily Show/
├── Season 2024/
│ ├── The Daily Show S2024E001 - 2024-01-02.mkv
│ └── The Daily Show S2024E002 - 2024-01-03.mkv
Episode number = day-of-year (001–366). Ugly but parser-clean. If the metadata provider (TVDB) supports the date-based show, NFO sidecars can override the episode title to the actual airdate.
2.6 Scrapers
- Primary: TheTVDB.
- Secondary: TheMovieDb (TMDb has good TV coverage too).
- Order matters: Library options → Metadata Fetchers → drag the order. For Futurama on this deploy we used TMDB primary because TVDB had stale episode-still URLs.
- Image: TVDB ships posters and episode stills; TMDB has higher-resolution backdrops; Fanart.tv has clearart + clearlogo.
2.7 Edge cases
- Series whose name STARTS with a year (e.g. "1923") — wrap in folder
1923 (2022)/so the parser doesn't confuse the series-name year with the disambiguation year. - Shows that re-run/reboot (
Doctor Who,Battlestar Galactica) — keep reboots in separate folders, year disambiguation is mandatory:Doctor Who (1963)/andDoctor Who (2005)/. - Mini-series / limited series — treat as TV, single season is fine
(
Chernobyl (2019)/Season 01/...). - Episode title inside filename is ignored once the series is identified; TMDB/TVDB title overwrites it (see doc 02 § 4).
(year)is required only at the series level, not on every episode. Including it on every episode is harmless but verbose.
3. Anime
Anime is the area with the highest "scraper picks the wrong thing" risk because TVDB / TMDB / AniDB / AniList disagree on how to slice multi-cours shows into seasons. Two distinct strategies — pick one per show, never mix.
3.1 Strategy A — TVDB seasonal numbering (default for this deploy)
Use this when:
- Show has ≤ 100 episodes.
- TVDB's season split matches the official Blu-ray / streaming split.
- You're not running Shoko.
Folder structure
/media/anime/
├── Cowboy Bebop (1998)/
│ └── Season 01/
│ ├── Cowboy Bebop (1998) S01E01.mkv
│ └── Cowboy Bebop (1998) S01E02.mkv
└── Mushishi (2005)/
├── Season 01/
└── Season 02/ ← Mushishi Zoku Shou maps to S02 on TVDB
Filename pattern
Identical to TV shows § 2.2. Include (year) of first broadcast.
Edge case — episodes >99 in a season
S01E100 works for the parser. S01E001 (3-digit) also works — see Issue
#17 in jellyfin-plugin-anime.
But absolute numbering across multiple seasons (where the show has 1099
episodes spanning many "seasons" on disk) breaks the seasonal model. Use
Strategy B.
3.2 Strategy B — Absolute numbering with Shoko Server
Use this when:
- Show has > 100 episodes (One Piece, Naruto, Detective Conan).
- You want AniDB matching, MAL/AniList sync, exact tag accuracy.
- You don't mind running an extra container.
Shoko hashes files by content (ED2K) and identifies them regardless of filename. With Shoko + the Jellyfin Shoko plugin, filenames don't matter.
/media/anime-shoko/
└── (any layout you like; Shoko walks the tree and hashes everything)
This deploy does not currently run Shoko. If/when added, it lives at
/opt/docker/shoko/ and exposes /media/anime-shoko/ to Jellyfin via the
plugin, separate from /media/anime/.
3.3 Strategy C — Absolute numbering with naive Jellyfin (avoid)
Naming files One Piece - 1099.mkv with no season folders works for the
very first 99 episodes then breaks: the parser sees ep 100+ as "ep 1
of S00 (Specials)" and shuffles. Documented in upstream issue #17. Don't.
3.4 Sub vs Dub
Two acceptable patterns:
Pattern 1 — separate libraries (recommended, clean):
/media/anime/Death Note (2006)/Season 01/Death Note (2006) S01E01.mkv ← original Japanese w/ subs
/media/anime-dub/Death Note (2006)/Season 01/Death Note (2006) S01E01.mkv ← English dub
Two libraries; user picks which to browse.
Pattern 2 — multi-version filenames (single library, may confuse scraper):
/media/anime/Death Note (2006)/Season 01/
├── Death Note (2006) S01E01.mkv ← default (sub)
└── Death Note (2006) S01E01 - Dub.mkv ← extra version, label "Dub"
Beware: multi-version on TV episodes (vs movies) is partial in Jellyfin 10.10 — the dub version may not be selectable from all clients. Pattern 1 is safer.
3.5 OVAs / OADs / specials
OVAs go in Season 00 of the parent series, with descriptive titles:
Mushishi (2005)/
├── Season 00/
│ ├── Mushishi (2005) S00E01 - Hihamukage OVA.mkv
│ └── Mushishi (2005) S00E02 - Bell of Stillness OVA.mkv
└── Season 01/
3.6 Anime films that are "part of" a show
Two camps:
- Canon to plot, watch-order matters (e.g. Code Geass: Lelouch of the
Re;surrection) → put in
Season 00of the show as a special. - Standalone film, parallel universe (most One Piece movies, Pokémon
films) → put in
/media/movies/with year. Provider IDs prevent cross-matching with the parent series.
3.7 Japanese vs English titles
Folder name uses the title that matches your primary metadata provider's
preferred display language. On this deploy, library MetadataLanguage is
pl for Futurama; if you add an Anime library set it to en or ja-JP.
Practical rule: use the romaji or English title that the show's English Wikipedia article uses as its primary heading. That's what TVDB/TMDB search will resolve. Set provider ID to lock if both titles match something:
/media/anime/Steins;Gate (2011) [tvdbid-244061]/
(Note ; is illegal on Windows but allowed on ext4. Avoid for portability.)
3.8 Scrapers
- Primary (sub library): TheTVDB (anime detection enabled).
- Optional plugin: AniDB + AniList plugins — install via Dashboard → Plugins → Catalog. Enable per-library. AniDB has better episode-level metadata for older shows; AniList has better current-airing data.
- With Shoko: Shoko replaces all of the above; AniDB IDs are canonical.
3.9 Library type
For this deploy, the Anime library uses CollectionType: tvshows (NOT a
separate "anime" type — Jellyfin doesn't have one). Set
PreferredMetadataLanguage and the metadata-provider order at library
creation. See § 12 for the API call.
4. Stand-up comedy specials
4.1 Folder structure
Treat as movies (one folder per special). Each comedian's specials are peers — do not nest by performer.
/media/movies/
├── Bo Burnham - Inside (2021)/
│ └── Bo Burnham - Inside (2021).mkv
├── Bo Burnham - Make Happy (2016)/
│ └── Bo Burnham - Make Happy (2016).mkv
└── Norm Macdonald - Nothing Special (2022)/
└── Norm Macdonald - Nothing Special (2022).mkv
4.2 Filename pattern
Same as Movies (§ 1.2). Convention: <Performer> - <Special Title> (year).
Examples that WORK
Bo Burnham - Inside (2021).mkv
Hannah Gadsby - Nanette (2018) [imdbid-tt8465676].mkv
Examples that BREAK
Bo Burnham/Inside (2021).mkv ← no per-movie folder
Inside (2021).mkv ← title too generic; TMDB picks horror film "Inside"
Bo Burnham: Inside (2021).mkv ← `:` is illegal
4.3 Scrapers
- Primary: TheMovieDb (TMDb has stand-up special listings under "Movies").
- TVDB has a Stand-Up category but the Jellyfin TVDB integration treats everything in a movies library as a movie — leave it.
4.4 Edge cases
- Specials that aren't on TMDB (small comedians, festival recordings) →
write a
movie.nfo(§ 11) and let it stand alone. Jellyfin won't fetch remote data without an ID. - Optional separate library: if you want stand-up out of the main movies
grid, create a second library with
CollectionType: moviesrooted at/media/standup/— same scrapers, just a different shelf. - Tagging: add
<tag>Stand-up</tag>to the NFO or use a Jellyfin Collection (BoxSet) called "Stand-up Specials" to group them.
5. Concerts / music videos
5.1 Folder structure
/media/musicvideos/
├── Daft Punk/
│ ├── Get Lucky/
│ │ └── Daft Punk - Get Lucky.mp4
│ └── Around the World/
│ └── Daft Punk - Around the World.mp4
└── Pink Floyd/
└── Pulse Concert (1995)/
├── Pink Floyd - Pulse (1995).mkv
└── poster.jpg
The library can nest as deep as you like — verbatim from upstream: "The folders and video files can be named however you want, since no metadata fetching is performed."
5.2 Filename pattern
- Pattern: anything. Free-form. The display name is the literal filename minus extension.
- Convention for this deploy:
<Artist> - <Track Title>.<ext>(or<Artist> - <Concert Name> (year).<ext>for full concerts).
Examples that WORK
Anything not containing < > : " / \ | ? *.
Examples that BREAK (parser-wise — none, but UX-wise)
01.mp4 ← display name "01", useless
videoplayback (1).mp4 ← yt-dlp default; rename before scan
5.3 Scrapers
- None by default.
musicvideoslibrary type has no built-in remote metadata fetcher — Jellyfin uses filenames + folder structure. - Embedded ID3-style tags in
mp4(artist, title) ARE read. - Plugins: there is no first-party music-video scraper. Some users use the MusicBrainz plugin to cross-reference, but coverage is poor.
5.4 Edge cases
- Full live concerts are sometimes better as
tvshows(one episode per song) ormovies(single file). For this deploy use movies for full concert recordings, musicvideos for individual song clips. - Fan-made / unofficial videos — fine here, since no scraper to mismatch.
- Music VIDEOS attached to a music album — Jellyfin doesn't link a music-video item to a music-album item natively. Live with the separation.
6. Documentaries
Documentaries split on form:
6.1 Single-film documentaries → Movies library
/media/movies/
└── Free Solo (2018)/
└── Free Solo (2018).mkv
Same rules as § 1. TMDB classifies most documentary films as "Movies".
6.2 Multi-episode documentary series → TV library
/media/tv/
└── Planet Earth II (2016)/
└── Season 01/
├── Planet Earth II (2016) S01E01.mkv
└── Planet Earth II (2016) S01E02.mkv
Same rules as § 2. TVDB classifies most documentary series as "Series".
6.3 Optional separate libraries
For users who want documentaries off the main Movies/TV shelves:
/media/docs-movies/withCollectionType: movies/media/docs-tv/withCollectionType: tvshows
Same scrapers as the parent type — the tag is purely UI.
6.4 Scrapers
- Films: TMDb (primary), OMDb (fallback).
- Series: TVDB (primary), TMDb (secondary).
- The same NFO override rules apply (§ 11) for obscure docs that aren't on any provider.
6.5 Edge cases
- Mini-series in 1 long file (e.g. The Vietnam War PBS, 18 hours, one rip) — treat as a movie or split into episodes. Jellyfin does not chapter- split a single file into N episode entries.
- Lecture series (Crash Course, Khan Academy) — treat as TV. Use
Crash Course (2011)/Season 01/etc.
7. Home videos / personal media
The goal: keep Jellyfin from "fixing" your wedding videos by pulling the poster of an unrelated 2015 movie called Wedding.
7.1 Folder structure
/media/home/
├── 2024/
│ ├── 2024-06-15 Berlin Trip/
│ │ ├── 2024-06-15 Berlin Trip - clip01.mp4
│ │ └── 2024-06-15 Berlin Trip - clip02.mp4
│ └── 2024-12-25 Christmas/
│ └── 2024-12-25 Christmas.mp4
└── 2025/
└── 2025-08-30 Wedding/
└── 2025-08-30 Wedding.mp4
7.2 Filename pattern
Free-form. Date-prefix recommended (YYYY-MM-DD <event>) — Jellyfin will
parse the date and use it as the item's date.
7.3 Library type
CollectionType: homevideos — critical. This is the only collection
type that disables all remote metadata fetchers. With homevideos:
- No TMDB / TVDB / OMDb scrapers run.
- Image fetchers are off (use sidecar
.jpgif you want a thumb). - The library shows up under "Photos & home videos" in the UI sidebar.
7.4 Scrapers
None. Local-only. NFO sidecars (§ 11) work if you want to label individual clips, but no remote lookups.
7.5 Edge cases
- Photos in the same folder as videos —
homevideoslibrary accepts both. Use.jpg/.png/.heicsidecars; they appear in the slideshow. - Don't drop home videos in
/media/movies/. Even with no provider IDs, Jellyfin will scan and try to match titles against TMDB. Thehomevideoslibrary is the only safe place. - Smart phone clips named
IMG_1234.MOVare fine; they display by filename. Bulk-rename to2024-06-15 - IMG_1234.movif you want them sorted by event date.
8. Extras / special features
Extras attach to a parent item (movie or series) via two mechanisms: filename suffix, or named subfolder. Either works; mixing is fine.
8.1 Suffix method
Append one of these tokens to the filename before the extension:
| Suffix | Type | Example |
|---|---|---|
-trailer .trailer _trailer trailer |
Trailer | Blade Runner (1982) - 1982 Theatrical-trailer.mp4 |
-sample .sample _sample sample |
Sample | Movie-sample.mp4 |
-scene |
Deleted scene / vignette | Inception (2010) - Hallway-scene.mp4 |
-clip |
Promo clip | Movie - TV Spot-clip.mp4 |
-interview |
Interview | Movie - Director Interview-interview.mp4 |
-behindthescenes |
BTS featurette | Movie - VFX Breakdown-behindthescenes.mp4 |
-deleted -deletedscene |
Deleted scene | Movie - Cut Diner Scene-deleted.mp4 |
-featurette |
Featurette | Movie - Anatomy of a Stunt-featurette.mp4 |
-short |
Short film | Movie - Prequel Short-short.mp4 |
-other -extra |
Catch-all | Movie - Ephemera-other.mp4 |
A lone trailer/sample file can also be named just trailer.mp4 or
sample.mp4 and dropped in the parent item folder.
8.2 Folder method
Inside the parent item folder, any of these named subfolders are picked up and the files inside are tagged with the matching extra type:
Inception (2010)/
├── Inception (2010).mkv
├── behind the scenes/
│ └── VFX Breakdown.mp4
├── deleted scenes/
│ ├── Diner Cut.mp4
│ └── Hotel Hallway Cut.mp4
├── featurettes/
│ └── Dreams Within Dreams.mp4
├── interviews/
│ └── Christopher Nolan.mp4
├── scenes/
├── shorts/
├── samples/
├── trailers/
│ └── Theatrical Trailer.mp4
├── clips/
├── theme-music/
│ └── theme.mp3 ← see § 8.3
├── backdrops/
│ └── 2.mp4 ← rotating video backdrops
├── other/
└── extras/ ← generic catch-all
Subfolder names must match exactly (case-insensitive on ext4+Jellyfin):
Behind the Scenes/ works; BTS/ does not; behind-the-scenes/ does not.
8.3 Theme music
theme-music/theme.mp3 plays a track on hover/auto in supported clients
(Swiftfin, JellyfinMediaPlayer). One file per item.
8.4 Backdrops
Video backdrops (rotating background loops) go in backdrops/ as numbered
mp4s. Falls back to image backdrops if not present.
8.5 Edge cases
- Extras attached to a series vs a season vs an episode — folder method
works at any level: drop
behind the scenes/insideFuturama (1999)/for series-wide extras, insideSeason 01/for season extras, or use suffix on a sibling file for episode extras. - Show-level trailers — Jellyfin's TV scraper auto-attaches trailer YouTube links from TMDB. You don't need to download them.
9. Subtitles (sidecar)
See 03-subtitles.md for the full rules. Quick reference:
<videobasename>.<lang>[.flag].<ext>
<videobasename>= the video filename minus extension.<lang>= ISO-639-1 (en,pl) or ISO-639-2 (eng,pol).<flag>= optional, any combination offorced,default,sdh,cc.<ext>=srt,ass,ssa,vtt,sub(+.idxfor VobSub).
Examples next to Futurama.s01e01.pl.mkv:
Futurama.s01e01.pl.eng.srt ← English regular
Futurama.s01e01.pl.en.forced.srt ← English forced (foreign-scene captions)
Futurama.s01e01.pl.en.sdh.srt ← English SDH
Futurama.s01e01.pl.en.default.srt ← marked default, auto-selects
Futurama.s01e01.pl.pl.srt ← Polish (matches the language of the audio)
After dropping subs on disk, run POST /Library/Refresh (or wait for the
nightly scan) — Jellyfin discovers them and attaches.
10. Artwork override files
Jellyfin scrapes artwork from TMDB/TVDB/Fanart by default (see doc 01). Override per-item by dropping a sidecar image with one of these recognised filenames in the item's folder.
10.1 Movie / generic item folder
| Filename | ImageType | Notes |
|---|---|---|
poster.jpg / poster.png |
Primary | Main poster (vertical 2:3). |
folder.jpg |
Primary | Alias of poster (Windows / Plex compat). |
cover.jpg |
Primary | Alias of poster (also used in music). |
default.jpg |
Primary | Alias. |
movie.jpg |
Primary | Alias. |
backdrop.jpg |
Backdrop | Hero image (16:9 fanart). |
backdrop1.jpg, backdrop2.jpg, ... |
Backdrop | Multiple backdrops, numbered. |
fanart.jpg |
Backdrop | Plex/Kodi compat alias. |
logo.png |
Logo | Transparent text-logo overlay. |
clearlogo.png |
Logo | Alias. |
banner.jpg |
Banner | Wide ~758×140 strip. |
thumb.jpg |
Thumb | 16:9 still. Used as episode thumbnail at item level. |
landscape.jpg |
Thumb | Alias. |
disc.png |
Disc | DVD/Blu-ray hub icon. |
clearart.png |
Art | Transparent character cutout. |
10.2 TV series folder (additional)
Futurama (1999)/
├── poster.jpg
├── backdrop.jpg
├── logo.png
├── banner.jpg
├── season-all-poster.jpg ← shared across all seasons
├── season01-poster.jpg ← Season 01 specific
├── season02-poster.jpg
├── season-specials-poster.jpg ← Season 00
├── Season 01/
│ ├── Futurama (1999) S01E01.mkv
│ ├── Futurama (1999) S01E01.jpg ← episode thumb (basename match)
│ └── poster.jpg ← also valid as season poster
└── tvshow.nfo
The two season-poster paths are equivalent; pick one style. Episode-level
thumbs use <basename>.jpg (i.e. drop a .jpg next to the .mkv with
matching name).
10.3 When to override
- Use sidecar files when the scraper's choice is wrong AND you don't want
to upload via the Web UI (which writes into
/config/metadata/library/...— wiped on container rebuild). - Sidecars in the media folder survive
docker rmbecause they live on the user's data volume. - Sidecars take precedence over remote scraper images on next refresh ONLY if "Save artwork into media folders" is enabled in Dashboard → Libraries → (each library) → Library options. This deploy has it ON.
10.4 Edge cases
.pngand.jpgare both accepted;.webpworks for backdrops but not all clients render it — prefer.jpg.- Image larger than 4K is downscaled by the API on serve. Don't bother with
2160p source images.
- Don't put
poster.jpgin/media/movies/(the library root) — it becomes the library's primary image, often unwanted.
11. NFO sidecars
NFO files are XML metadata, written next to the media. They override remote scrapers entirely. From upstream: "Local metadata will always be fetched and has priority over remote metadata providers like TMDb."
11.1 Filenames
| Item type | Required filename |
|---|---|
| Movie | movie.nfo (in the movie folder), OR <videobasename>.nfo next to the file, OR VIDEO_TS.nfo for DVD rips |
| TV series | tvshow.nfo in the series folder |
| TV season | season.nfo in the season folder |
| TV episode | <episode_filename>.nfo (e.g. Futurama (1999) S01E01.nfo) |
| Music artist | artist.nfo |
| Music album | album.nfo |
11.2 When to write one
- Obscure indie film not on TMDB / IMDB →
movie.nfolets you fill the metadata yourself. - Show whose IDs scrape wrong every time →
tvshow.nfowith locked<tmdbid>/<tvdbid>is faster than the APIRemoteSearch/Applyworkflow (doc 02 § 5). - Home videos / personal — usually not needed (homevideos lib doesn't scrape) but useful for nice titles.
11.3 Minimal movie.nfo example
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<movie>
<title>The Obscure Film</title>
<originaltitle>Niejasny film</originaltitle>
<year>2014</year>
<plot>A short description that overrides whatever TMDB returns.</plot>
<genre>Drama</genre>
<runtime>97</runtime>
<director>Jane Director</director>
<actor>
<name>Lead Actor</name>
<role>Protagonist</role>
</actor>
<uniqueid type="imdb" default="true">tt12345678</uniqueid>
</movie>
11.4 Minimal tvshow.nfo example
<?xml version="1.0" encoding="UTF-8"?>
<tvshow>
<title>Futurama</title>
<year>1999</year>
<plot>...</plot>
<uniqueid type="tmdb" default="true">615</uniqueid>
<uniqueid type="tvdb">73871</uniqueid>
</tvshow>
11.5 NFO Saver (write-back)
Enable Dashboard → Libraries → (each) → Metadata Savers → "Nfo". Jellyfin
will write *.nfo next to media files whenever metadata changes. This is
how you survive container rebuilds without losing manual fixes — the NFO
on disk is canonical, the SQLite DB is regenerable.
11.6 Edge cases
- Empty/malformed NFO stops the scraper from running on that item AT ALL. Either write valid XML or delete the file.
- NFO + provider ID conflict — local always wins. If you set
<tmdbid>615</tmdbid>and the filename has[tmdbid-9999], NFO wins. - Episode
.nfoper file is verbose. Most people only writetvshow.nfoand let the episode metadata come from the provider.
12. CollectionType-to-scraper mapping (library creation)
Verbatim values from Jellyfin.Data/Enums/CollectionType.cs (master,
verified 2026-05). These are the strings to pass when creating a library
via API. (unknown is reserved; tvshowseries+ are virtual aggregates not
used at library creation.)
CollectionType |
UI name | Default scrapers (10.10.x) | Use for |
|---|---|---|---|
movies |
Movies | TMDb, OMDb, Fanart.tv (plugin) | Films, stand-up, doc films |
tvshows |
Shows | TVDB, TMDb, Fanart.tv, OMDb | TV, anime, doc series, kids' shows |
music |
Music | MusicBrainz, AudioDB | Albums, tracks |
musicvideos |
Music Videos | none (filename only) | Music videos, short concerts |
homevideos |
Home Videos & Photos | none | Personal recordings, photo albums |
boxsets |
Collections | TMDb collections | Manually-curated cross-library box sets |
books |
Books | requires "Bookshelf" plugin | epub, mobi, pdf, comics |
photos |
Photos | none | Photo-only library |
livetv |
Live TV | tuner-driven | Real-time TV (HDHomeRun etc.) |
trailers |
Trailers | bundled | Standalone trailers library (rare) |
playlists |
Playlists | n/a | Internal Jellyfin construct |
folders |
Folders | n/a | Internal Jellyfin construct |
mixed (no enum, legacy) |
Mixed | TMDb + TVDB | Don't use — drops most parsing rules |
12.1 Creating libraries via API
TOKEN=<JELLYFIN_API_TOKEN>
H="-H \"X-Emby-Token: ${TOKEN}\""
B="https://arrflix.s8n.ru"
# Movies library
curl -s -X POST $H "$B/Library/VirtualFolders?name=Movies&collectionType=movies" \
-H "Content-Type: application/json" \
-d '{"LibraryOptions":{"PathInfos":[{"Path":"/media/movies"}],"EnableInternetProviders":true,"PreferredMetadataLanguage":"en","MetadataCountryCode":"US","SaveLocalMetadata":true,"SubtitleDownloadLanguages":["eng"]}}'
# TV library
curl -s -X POST $H "$B/Library/VirtualFolders?name=Shows&collectionType=tvshows" \
-H "Content-Type: application/json" \
-d '{"LibraryOptions":{"PathInfos":[{"Path":"/media/tv"}],"EnableInternetProviders":true,"PreferredMetadataLanguage":"en","SaveLocalMetadata":true,"SubtitleDownloadLanguages":["eng"]}}'
# Anime library (still tvshows type)
curl -s -X POST $H "$B/Library/VirtualFolders?name=Anime&collectionType=tvshows" \
-H "Content-Type: application/json" \
-d '{"LibraryOptions":{"PathInfos":[{"Path":"/media/anime"}],"EnableInternetProviders":true,"PreferredMetadataLanguage":"en","SaveLocalMetadata":true,"SubtitleDownloadLanguages":["eng"]}}'
# Music videos
curl -s -X POST $H "$B/Library/VirtualFolders?name=Music%20Videos&collectionType=musicvideos" \
-H "Content-Type: application/json" \
-d '{"LibraryOptions":{"PathInfos":[{"Path":"/media/musicvideos"}]}}'
After creation, trigger an initial scan: POST /Library/Refresh.
13. Canonical layout for THIS deploy
13.1 Architecture decision
Adopted: Architecture A — flat by category at /home/user/media/, one
Jellyfin library per category.
/home/user/media/
├── movies/ ← collectionType: movies
└── tv/ ← collectionType: tvshows
ARRFLIX scope locked 2026-05-08: TV Shows + Movies only.
anime/,musicvideos/,home/,music/,docs-*/libraries removed. Sections in this doc covering anime/music/etc. remain as reference for the day scope is revisited — justmkdir+ add library via API when needed.
13.2 Why Architecture A (not B or C)
B (nested, media/video/{movies,tv,anime}/...) — rejected. Adds a
useless directory level. Jellyfin's library config takes a path; nesting
buys nothing on the client side. Increases the chance of a typo in the
container's bind-mount.
C (split disks: /media-fast/ NVMe + /media-slow/ HDD) — rejected
for now. Nullstone has a single 2 TB NVMe and 4 TB HDD. Total media
today is ~50 GB (Futurama + future). When the library exceeds 1 TB, we'll
revisit and migrate cold catalogue (older movies, finished anime) to the
HDD, mounted as a second library path:
LibraryOptions.PathInfos = [
{"Path": "/media/movies"}, ← /home/user/media/movies on NVMe
{"Path": "/media-archive/movies"} ← /mnt/hdd/media/movies
]
Jellyfin natively merges multiple paths into one logical library. No URL or client-facing change needed at migration time.
A wins because:
- One library per
collectionTypeis the simplest correct mapping.
13.3 Concrete mkdir commands
Run on nullstone as user (not root — the existing tree is already owned
by user:user):
ssh user@192.168.0.100 'mkdir -p \
/home/user/media/movies \
/home/user/media/tv'
Verify:
ssh user@192.168.0.100 'ls -la /home/user/media/'
13.4 Container bind mounts
/opt/docker/jellyfin/docker-compose.yml should mount each as read-only
under /media/<name>:
volumes:
- /home/user/media/movies:/media/movies:ro
- /home/user/media/tv:/media/tv:ro
13.5 Initial state after applying
Movies library → /media/movies (empty, ready)
TV Shows library → /media/tv (Futurama 1999, S01-S04, 72 eps + 9 featurettes)
14. Verification checklist
Before declaring a new addition "done":
- Filename matches the regex anchor for the category (§ 1–7).
- Year is in
(YYYY)and matches the actual release year. - Folder name byte-for-byte matches the filename prefix (movies multi-version).
- No forbidden chars (
< > : " / \ | ? *). - Per-item folder exists (no loose files in library root, except music videos).
tvshow.nfo/movie.nfoexists IFF you needed to override the scraper.- Subtitles use
<basename>.<lang>.srt(doc 03). - Scan:
curl -s -X POST -H "X-Emby-Token: $TOKEN" https://arrflix.s8n.ru/Library/Refresh. - Wait ~30 s, check item via
/Items?searchTerm=...— verifyProviderIdsis populated. EmptyProviderIds= filename didn't disambiguate; doc 02 § 5 has the manual-lock recipe. - Refresh (
Items/{id}/Refresh?ReplaceAllMetadata=true) AFTER fixing the provider ID — otherwise the wrong cached metadata sticks.
15. Quick reference card
| Category | Folder | Filename | CollectionType | Scraper |
|---|---|---|---|---|
| Movie | movies/Title (year)/ |
Title (year).mkv |
movies |
TMDb |
| Movie multi-version | movies/Title (year)/ |
Title (year) - 1080p.mkv |
movies |
TMDb |
| Movie multi-disc | movies/Title (year)/ |
Title (year) - cd1.mkv |
movies |
TMDb |
| TV episode | tv/Show (year)/Season 01/ |
Show (year) S01E01.mkv |
tvshows |
TVDB |
| TV multi-ep | tv/Show (year)/Season 01/ |
Show (year) S01E01-E02.mkv |
tvshows |
TVDB |
| TV special | tv/Show (year)/Season 00/ |
Show (year) S00E01.mkv |
tvshows |
TVDB |
| Anime (seasonal) | anime/Show (year)/Season 01/ |
Show (year) S01E01.mkv |
tvshows |
TVDB+AniDB plugin |
| Anime (Shoko) | anime-shoko/<any> |
any | tvshows |
Shoko |
| Stand-up | movies/Comedian - Title (year)/ |
Comedian - Title (year).mkv |
movies |
TMDb |
| Music video | musicvideos/Artist/Track/ |
Artist - Track.mp4 |
musicvideos |
none |
| Doc film | movies/Title (year)/ |
Title (year).mkv |
movies |
TMDb |
| Doc series | tv/Show (year)/Season 01/ |
Show (year) S01E01.mkv |
tvshows |
TVDB |
| Extra (suffix) | movies/Title (year)/ |
Anything-behindthescenes.mp4 |
(parent) | n/a |
| Extra (folder) | movies/Title (year)/behind the scenes/ |
any | (parent) | n/a |
16. Top three gotchas (in order of frequency)
- No per-item folder. Loose
Movie (2020).mkvdirectly in/media/movies/parses, but extras / NFO / artwork sidecars cannot attach. Always make a folder. - Year not in parens.
Movie 2020.mkv→ year is part of the title; scraper search for "Movie 2020" returns wrong results. AlwaysMovie (2020).mkv. - Anime absolute numbering > 99 episodes without Shoko, mixed with season folders → episodes shuffle into Season 0. Either split by TVDB seasons OR run Shoko. Never half-and-half.
End of doc 05. For questions about parsing edge cases not covered here,
read Emby.Naming.xml inside the container (docker exec jellyfin cat /jellyfin/Emby.Naming.xml) — it has the canonical regex chain.