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
downloaded and searched subtitles, supports audio track selection, builds 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.

1.0 feature set

  • Responsive library browsing for movies, series, music, downloads, lists,
    people, catalog filters, metrics, and settings.
  • Localized UI with user-selectable English, Polish, German, French, Italian,
    Spanish, Chinese, and Japanese labels.
  • Background library scans with progress toasts, duplicate cleanup, subtitle
    discovery, album reconciliation, generated artwork tracking, and atomic
    publishing so the existing catalog remains browsable while a scan runs.
  • AI recommendations for movies, series, and music using user taste notes,
    watched/listened history, lists, and the current library.
  • Admin metadata cleanup powered by an OpenAI-compatible chat completion API,
    including per-title cleanup, queued cleanup actions, batch cleanup APIs,
    verbose logs, and artwork/synopsis refresh after labels are cleaned.
  • AI list and temporary music playlist creation with refinement before commit.
  • Subtitle manager with downloaded subtitles, provider search, ranked best
    matches, immediate activation after download, and OpenSubtitles/SubDL support.
  • Custom playback controls with keyboard/mouse handling, fullscreen behavior,
    next/previous queue controls, subtitle selection display, and selectable audio
    tracks when media exposes multiple tracks.
  • Social features for friends, recommendations, shared activity/taste privacy,
    user profiles, avatars, notifications, and user feedback.
  • Admin pages for feedback, movie requests, metrics, imports, and metadata
    cleanup, with resolved/handled previews where applicable.
  • API tokens, Swagger/OpenAPI access, and MCP tools for list management,
    preferences, AI recommendation, and admin movie-request review.

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. A scan
catalogs new files, discovers sidecar subtitles, imports music covers from album
folders, reconciles albums, and marks duplicate movie rows so they do not appear
as duplicate cards.

API and MCP access

Authenticated users can create API tokens from Settings -> API access. Tokens
are shown only once when created, can be revoked from the same settings panel,
and work as bearer tokens:

curl -H "Authorization: Bearer htv_your_token" http://localhost:8099/api/lists

The OpenAPI schema is available at /openapi.json, and the Swagger UI is linked
from settings as /api/docs (redirecting to /docs). Token-authenticated API
access supports normal user list management endpoints such as /api/lists,
/api/lists/{list_id}, and /api/lists/{list_id}/items. Admin tokens can also
read and update movie requests through /api/admin/movie-requests, run metadata
cleanup through /api/admin/metadata-cleanup, and inspect the catalog through
/api/admin/catalog, /api/admin/catalog-json, and /api/admin/catalog/search.

MCP clients can use the /mcp endpoint with the same bearer token. The endpoint
accepts JSON-RPC requests over HTTP and exposes tools for list management plus
admin-only movie request review:

curl -H "Authorization: Bearer htv_your_token" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' \
  http://localhost:8099/mcp

Available MCP tools include list_lists, get_list, create_list,
delete_list, add_list_item, remove_list_item, set_media_preference,
ai_recommend_movie, list_movie_requests, and update_movie_request. Movie
request admin tools require an admin token.

Users can score movies from 1-10 and mark titles as seen from the movie detail
view or through PUT /api/media/{media_id}/preference. When AI is configured,
the settings page exposes movie/series and music taste description fields.
Movie, series, and music sections show scoped AI recommendation buttons that ask
the configured OpenAI-compatible model for a library title using the user's
taste, watched or listened history, lists, and section-specific candidates.
Admins can also use AI cleanup endpoints to normalize media labels and refresh
metadata/artwork.

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. Direct imports, metadata cleanup, metrics, feedback
    review, and request handling are admin-only; basic library scans are available
    to authenticated users.
  • 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.
  • AI_API_URL, AI_API_KEY, AI_API_MODEL: optional OpenAI-compatible chat
    completion endpoint, bearer key, and model name. When all three are set,
    Home TV enables taste settings and AI recommendations for movies, series, and
    music, AI list creation, and admin metadata cleanup.
Gallery

Home-tv

Open gallery
Dashboard
Global searchMovie recapPlayer controlsSeries, details