Unified phone/web controller for a home room media stack (Cast, Fire TV, Apple TV, TCL, Sonos).
  • HTML 65.6%
  • Python 29.2%
  • Shell 5.2%
Find a file
Nidahl Damen 550f15e167 Home Media Control: unified room media controller (public release)
A single phone-friendly web page that proxies to per-device backend
services (Cast, Fire TV, Apple TV, TCL, Sonos) to search, play, and
control a whole living-room media stack from one panel. Standard-library
Python, no cloud, LAN-only.
2026-06-14 11:56:09 -07:00
.github/workflows Home Media Control: unified room media controller (public release) 2026-06-14 11:56:09 -07:00
deploy Home Media Control: unified room media controller (public release) 2026-06-14 11:56:09 -07:00
scripts Home Media Control: unified room media controller (public release) 2026-06-14 11:56:09 -07:00
systemd Home Media Control: unified room media controller (public release) 2026-06-14 11:56:09 -07:00
tests Home Media Control: unified room media controller (public release) 2026-06-14 11:56:09 -07:00
.gitignore Home Media Control: unified room media controller (public release) 2026-06-14 11:56:09 -07:00
.sanity-patterns.json Home Media Control: unified room media controller (public release) 2026-06-14 11:56:09 -07:00
index.html Home Media Control: unified room media controller (public release) 2026-06-14 11:56:09 -07:00
LICENSE Home Media Control: unified room media controller (public release) 2026-06-14 11:56:09 -07:00
qa-panel.md Home Media Control: unified room media controller (public release) 2026-06-14 11:56:09 -07:00
README.md Home Media Control: unified room media controller (public release) 2026-06-14 11:56:09 -07:00
server.py Home Media Control: unified room media controller (public release) 2026-06-14 11:56:09 -07:00
WHITEPAPER.md Home Media Control: unified room media controller (public release) 2026-06-14 11:56:09 -07:00

Home Media Control

One phone-friendly web page to drive your whole living-room media stack: search across your devices, pick where to watch, and control playback, volume, and power, all from your phone on the home network. No app to install, no cloud, no account.

The panel is a single, dependency-free Python file (server.py) plus one static page (index.html). It does not talk to your TV hardware directly. Instead it proxies to a handful of small local backend services you run alongside it, one per device type. You enable only the backends you own; the panel degrades gracefully when any of them is offline.

What it controls

Source Backend service (companion project) What you get
Cast (Google TV / Chromecast) google-cast-control (:4530) YouTube search + play, exact-second seek
Fire TV firetv-nowplaying (:4490) now-playing, seek, runtime, universal search, deep-links
Apple TV tcl-tv-mcp (:4480) + optional Apple TV helper input switch, key presses, now-playing, YouTube
TCL Google TV tcl-tv-mcp (:4480) power, app, D-pad / remote keys
Sonos a Sonos HTTP service (:52546) room volume, per-speaker volume, mute, surround grouping

The companion backends are separate projects; this repo is just the unified panel and the proxy in front of them. The panel speaks plain HTTP/JSON to each backend, so you can swap any of them for your own implementation as long as it exposes the same routes.

Requirements

  • Python 3.9+ (standard library only; no pip install for the panel itself)
  • One or more device backend services reachable over HTTP on your LAN

Install

git clone https://github.com/nidamen/home-media-control.git
cd home-media-control

That is it for the panel. Each device backend is its own project with its own setup.

Run

HOME_MEDIA_PORT=4520 python3 server.py

Open http://<this-machine-ip>:4520/ on your phone. The service binds to 0.0.0.0 by default so any phone on the LAN can reach it at the machine's current IP, with no hard-coded address in the page.

Configure

Everything is set with environment variables, so there are no IPs or secrets baked into the code. Point each *_BASE at wherever you run that backend:

Variable Default Purpose
HOME_MEDIA_PORT (or PORT) 4520 Port the panel listens on
HOME_MEDIA_HOST 0.0.0.0 Bind address
TCL_BASE http://127.0.0.1:4480 TCL / Apple TV remote backend
FIRE_NOW_BASE http://127.0.0.1:4490 Fire TV now-playing backend
CAST_BASE http://127.0.0.1:4530 Google Cast backend
SONOS_BASE http://127.0.0.1:52546 Sonos backend
SEARCH_BASE http://127.0.0.1:4540 Optional unified-search backend
DRDABBER_BASE http://127.0.0.1:4477 Optional extra device probe
APPLE_TV_MCP_PY python3 Python for the optional Apple TV YouTube helper
APPLE_TV_MCP_SRC (unset) PYTHONPATH for that helper, if used
APPLE_TV_MCP_MODULE apple_tv_mcp.watch Module run as python -m <module> "<query>"

Device IPs live in your backends (and in the example Environment= lines in deploy/), never in this panel.

Deploy

Run the panel (and your backends) as managed, auto-restarting services. See deploy/README.md:

  • macOS: sh deploy/install-mac.sh installs LaunchAgents.
  • Linux / Raspberry Pi: sudo deploy/install-pi.sh installs systemd units.
  • Single service only: systemd/home-media-control.service runs just the panel.

Health check: scripts/healthcheck.sh http://127.0.0.1:4520.

API

The panel exposes a small JSON API (full reference in WHITEPAPER.md):

  • GET /api/state - aggregated state of every backend
  • GET /api/health - 200 if all backends are up, 503 otherwise
  • GET /api/search?q= - unified search across catalog + YouTube
  • POST /api/source, /api/key - switch input, send remote keys
  • POST /api/cast/*, /api/fire/*, /api/atv/*, /api/sonos/* - per-device control

Tests

python3 -m unittest discover -s tests

The tests cover the routing and aggregation logic and need no hardware.

License

MIT. See LICENSE.