# the-guardian-snowden-2013-20130709 Single-video YouTube import into the **STOCK** Jellyfin at `tv.s8n.ru` (container `jellyfin-stock`), **Education** library (`collectionType=movies`, internet providers disabled). First import into a brand-new "The Guardian" channel folder. Exposed a single-file folder caveat in Jellyfin movie parsing — see Notes. ## Provenance - **Source:** YouTube — `https://www.youtube.com/watch?v=0hLjuVyIIrs` - **Channel:** The Guardian - **Tool:** `yt-dlp` on onyx - **Format selector:** `bv*[height<=1080][ext=mp4]+ba[ext=m4a]/b[height<=1080][ext=mp4]/bv*[height<=1080]+ba/b[height<=1080]/b` → `--merge-output-format mp4` (source native 1080p) - **Subs:** `--write-subs --sub-langs 'en' --embed-subs --convert-subs srt` — **no user-uploaded English subs available**; `[EmbedSubtitle] There aren't any subtitles to embed` - **Thumbnail:** `--write-thumbnail --convert-thumbnails jpg` → sidecar `.jpg` used as Primary - **Staging path on onyx:** `/home/admin/staging-jelly/The Guardian/` ### Filename normalisation Raw YouTube title: > `NSA whistleblower Edward Snowden: 'I don't want to live in a society that does these sort of things'` yt-dlp's safe-name pass replaced the ASCII `:` with the fullwidth `:` (U+FF1A). Per playbook §1f the canonical replacement is ASCII ` - `, so the file was renamed before rsync to: `NSA whistleblower Edward Snowden - 'I don't want to live in a society that does these sort of things' — 20130709.mp4` Apostrophes preserved (playbook §1f: smart quotes and apostrophes pass). ## Target - **Server:** `jellyfin-stock` on nullstone, public URL `https://tv.s8n.ru` - **Library:** Education (`collectionType=movies`, `EnableInternetProviders=false`) - **Path on host:** `/home/user/media/education/The Guardian/NSA whistleblower Edward Snowden - 'I don't want to live in a society that does these sort of things' — 20130709.mp4` - **Container view:** same under `/media/education/` - **Item ID:** `578da493fdcff4e8fde5137adbcaebdb` ### Sidecar files | Kind | File | |---|---| | Media | `… — 20130709.mp4` (46,324,047 B, ~44 MiB) | | Subtitle | none | | Thumbnail | `… — 20130709.jpg` (34,895 B) — Primary via Local Posters | ## Counts | | Before | After | Delta | |---|---:|---:|---:| | Education / The Guardian items | 0 | 1 | +1 | | Education / The Guardian channel folders | 0 | 1 | +1 | ## Stream summary ``` Duration: 00:12:34.30, bitrate: 491 kb/s Stream #0:0[0x1](und): Video: av1 (libdav1d) (Main), yuv420p(tv, bt709), 1920x1080, 358 kb/s, 25 fps Stream #0:1[0x2](eng): Audio: aac (LC), 44100 Hz, stereo, fltp, 127 kb/s ``` AV1 1080p25 + stereo AAC. No subtitle streams. ## Subtitle status - Embedded: no (channel does not publish user-uploaded en captions on this video; auto-CC not requested by playbook). - External sidecar: no. - Action: deferred. If subs become required, follow `playbooks/subtitles/` WhisperX pipeline (do **not** fall back to YouTube auto-CC; see `feedback_subtitle_accuracy_priority`). ## Verification checks - [x] Folder/filename canonical (`/ — <YYYYMMDD>.mp4`). - [x] No forbidden chars in path (fullwidth `:` → ` - ` rename in staging). - [x] Permissions `user:user` 644 / 755. - [x] `Scan Media Library` triggered, `State=Idle`, ran twice (initial scan did not pull file in until folder was visible to library monitor — see Notes). - [x] `/Items?searchTerm=NSA+whistleblower&IncludeItemTypes=Movie` returns the expected single item after `Name` lock. - [x] `ImageTags.Primary` present. - [ ] Direct-play in mobile / Smart-TV client not exercised. ## Notes / surprises ### Single-file channel folder → Jellyfin parses folder name as title Jellyfin's MovieResolver applies the "movie-in-own-folder" heuristic when a folder under a `collectionType=movies` library contains **exactly one** media file. The resulting `BaseItem.Name` is taken from the folder name, not the filename — so the Snowden mp4 initially indexed with `Name="The Guardian"` instead of the actual video title. Workaround used (no playbook change required for this run): ```bash # Pull current item, set Name explicitly, LockData=true, POST back ID=578da493fdcff4e8fde5137adbcaebdb curl -sf -H "X-Emby-Token: $TOK" \ "$SERVER_URL/Users/$USER_ID/Items/$ID" \ | jq '.Name = "NSA whistleblower Edward Snowden - ..." | .LockData = true' \ | curl -sf -X POST -H "X-Emby-Token: $TOK" -H 'Content-Type: application/json' \ --data @- "$SERVER_URL/Items/$ID" # expect HTTP 204; Name now locked so future refresh cannot revert it. ``` Generalises to any first-video import into a brand-new channel folder. Recommend documenting in `playbooks/import-media/README.md` §1d as a known caveat with the LockData fix; will propose a `playbooks/` PR after the second occurrence to confirm reproducibility. ### Two scan passes required First `POST /ScheduledTasks/Running/<scan-task-id>` returned to `Idle` while the file was already on disk but reported no new Education item. A second identical invocation indexed the file. Root cause unclear — possible `LibraryMonitor` race during inotify pickup of the freshly created folder. Documenting per playbook §5d / known-broken-trigger guidance.