Logo
Programming
Dashboard
DockerPythonJavaScriptReact
Programming project

Home-tv

Home TV is a self-hosted media app I’m building for my own home setup: movies, series, music, playlists, subtitles, cataloguing, recommendations, user activity, and admin tooling in one local-first interface.

Build notes

Home TV is a small self-hosted media server for personal libraries. It catalogs movie, TV, and music folders, streams files with HTTP range support, can start HLS transcodes with ffmpeg, imports Plex library database entries, manages local subtitles, supports music playlists with queue/shuffle playback, and supports direct HTTP(S) imports for media you are allowed to use.

It is intentionally not a torrent or piracy automation tool. Magnet links and .torrent inputs are rejected.

README

Home TV

Home TV is a small self-hosted media server for personal libraries. It catalogs
movie, TV, and music folders, streams files with HTTP range support, can start
HLS transcodes with ffmpeg, imports Plex library database entries, manages local
subtitles, supports music playlists with queue/shuffle playback, and supports
direct HTTP(S) imports for media you are allowed to use.

It is intentionally not a torrent or piracy automation tool. Magnet links and
.torrent inputs are rejected.

Preview

The screenshots below were captured from a live Home TV deployment with a real
library connected.

Home TV narrated overview

Watch the narrated overview on YouTube.

Dashboard

Movie recap

Music albums and queue

Admin metrics

More rollout screenshots are available in
docs/media/screenshots.

Local run

python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[test]"
cp .env.example .env
make run

Open http://localhost:8099, register the first account, then scan libraries.

Docker

make build
docker run --rm -p 8099:8099 \
  -e HOME_TV_SECRET_KEY=change-me \
  -v "$PWD/data:/data" \
  -v "/path/to/Movies:/data/movies:ro" \
  -v "/path/to/TV:/data/tv:ro" \
  -v "/path/to/Music:/data/music:ro" \
  home-tv:local

After the first run or library path changes, run a scan from the UI. Scans
catalog new files, discover sidecar subtitles, import music covers from album
folders, and mark duplicate movie rows so they do not appear as duplicate cards.

Useful environment

  • HOME_TV_SECRET_KEY: required in production.
  • HOME_TV_ADMIN_USERS: optional comma-separated usernames that should be
    promoted to admin on startup/login/registration. The first registered user is
    still admin by default. Admins can scan libraries and use direct imports.
  • HOME_TV_DATA_DIR: app database, posters, subtitles, and transcode cache.
  • HOME_TV_MOVIES_DIR, HOME_TV_TV_DIR, HOME_TV_MUSIC_DIR: library roots.
  • HOME_TV_DOWNLOADS_DIR: direct import target.
  • HOME_TV_SUBTITLES_DIR: optional external subtitle store.
  • HOME_TV_PLEX_CONFIG_DIR: Plex config root for database discovery.
  • HOME_TV_PLEX_DB_PATH: explicit Plex SQLite database path.
  • OPENSUBTITLES_API_KEY, OPENSUBTITLES_USERNAME, OPENSUBTITLES_PASSWORD:
    optional OpenSubtitles credentials. The API key enables provider access;
    username/password are needed for the login token flow used by authenticated
    downloads.
  • SUBDL_API_KEY: optional SubDL subtitle search/download credential.
  • OMDB_API_KEY: optional metadata credential. When set, Plex import also asks
    OMDb for IMDb/Rotten Tomatoes/Metacritic-style ratings and stores them on the
    media row. Without it, Home TV displays the critic/audience ratings already
    imported from Plex.
  • TMDB_API_KEY or TMDB_READ_ACCESS_TOKEN: optional but recommended for
    public movie/series discovery in the global search dropdown. When absent,
    Home TV falls back to OMDb/iTunes for movies and TVmaze for series.
  • HOME_TV_MUSICBRAINZ_ENABLED: optional public music discovery toggle.
    Defaults to true; MusicBrainz is used for remote album search instead of
    iTunes.
  • MUSICBRAINZ_USER_AGENT: optional MusicBrainz user agent string. Set this to
    identify your deployment if you publish or share the service.
  • HOME_TV_TVMAZE_ENABLED: optional TV episode metadata toggle. Defaults to
    true; scans use TVmaze to replace filename-derived episode labels when a
    show, season, and episode number can be matched.
Gallery

Home-tv

Open gallery
Dashboard
Global searchMovie recapPlayer controlsSeries, details