SKYHOUSE.dev Journal

Maintaining the Cloud Fortress

yt-plex: An Arr for Everything That Isn't a Torrent

Why: Damien wanted an arr-style web page for YouTube (and other yt-dlp) content: paste URLs, tag each with a library, hit Go, and have the files land in Plex already named correctly, including YouTube shows that TVDB tracks as real series.

We built yt-plex, a small FastAPI app at /home/plex/yt-plex. It runs as a systemd user service on port 8430. The page is a queue. You paste a URL and it immediately runs a yt-dlp metadata lookup (title, thumbnail, description, upload date, available resolutions, approximate size), then a fresh input appears underneath for the next URL. Each row has a library dropdown, a quality picker, an editable name box and its own Go button, and Go All at the bottom sweeps up everything not yet started. Progress streams live to the page.

1. How it works

2. TV shows and TVDB matching

Scraping thetvdb.com was fragile and the v4 API wants a paid key. Instead we used the service Sonarr already relies on: Skyhook (skyhook.sonarr.tv/v1/tvdb/shows/en/<tvdbId>) returns a show's full episode list with air dates and needs no key. Matching looks for an episode within ±1 day of the YouTube upload date and breaks ties by title similarity. If nothing is that close, it falls back to title similarity alone (≥60%). The row shows how it matched, and an episode dropdown lets you override it. The name becomes S2026E29 Everyone Hates Flock Cameras, and the files, including the JPG, go into a folder of that name under the show.

Seeded shows: Some More News (335826), Philosophy Tube (370485), Patrick (H) Willems (365605 → folder Patrick H Willems), ContraPoints (370198 → Contrapoints) and hbomberguy (370652). The TV Shows dialog adds more from a TVDB URL, an ID or a search. TVDB slugs drift (Damien's SMN link says some-news but the current slug is some-more-news), so slug URLs are resolved by reading the series ID off the page. Channel names are matched to shows automatically, so pasting a Some More News link preselects TV Shows, the show and the episode.

A known gap: TVDB volunteers sometimes list an episode a day or two late. The row then says so, and ↻ re-checks.

3. The app's own yt-dlp

The system /usr/local/bin/yt-dlp zipapp got HTTP 429 on every subtitle fetch, because it has no curl_cffi for browser impersonation. It also reads Damien's personal config: --restrict-filenames would mangle titles into underscores, and --download-archive would silently skip re-downloads. So the app runs --ignore-config with its own yt-dlp installed in the venv as yt-dlp[default,curl-cffi], using deno (~/.deno/bin/deno) as the JS runtime.

4. Verification

5. Going live (completed September 29)

Net effect: YouTube content now has the same paste-and-forget path into Plex that the arrs give torrents, with TVDB-correct episode naming for YouTube series.

← Back to Admin Hub