Summary
A web version of CastToTV — open a page in any browser (incl. phone) and cast.
Honest browser constraints (why a pure public site can't do it all)
A web page cannot open UDP/SSDP (DLNA discovery), use raw sockets, scan the /24, run ffmpeg/yt-dlp, or SOAP arbitrary IPs (CORS). It can cast a media URL to Chromecast (Google Cast SDK, Chrome/Edge) and to AirPlay (Safari <video>). So the casting/transcoding/discovery has to live in a backend.
Two tiers
Tier 1 — pure public browser (no install):
- Chromecast via the Cast SDK + Safari AirPlay; "paste a URL → cast" only.
- No DLNA, no discovery, no transcode, no yt-dlp, no multi-room.
Tier 2 — public frontend + local agent (full features, recommended):
- The headless
CastingController (#) runs as a small local daemon (FastAPI + WebSocket) on the user's PC / Raspberry Pi / home server.
- The hosted single-page app pairs with that agent over the LAN (or a relay) and drives discovery + DLNA/Chromecast/AirPlay + multi-room + radio/cover-art through it.
- Reuses the existing media servers as-is (
HTTPServerThread :8766, the streamer servers :8768).
- This is the Jellyfin / Home Assistant model wearing a public URL: the site is public, the casting happens on the user's network via the agent.
Scope
Acceptance
Depends on the headless CastingController foundation (#).
Summary
A web version of CastToTV — open a page in any browser (incl. phone) and cast.
Honest browser constraints (why a pure public site can't do it all)
A web page cannot open UDP/SSDP (DLNA discovery), use raw sockets, scan the
/24, run ffmpeg/yt-dlp, or SOAP arbitrary IPs (CORS). It can cast a media URL to Chromecast (Google Cast SDK, Chrome/Edge) and to AirPlay (Safari<video>). So the casting/transcoding/discovery has to live in a backend.Two tiers
Tier 1 — pure public browser (no install):
Tier 2 — public frontend + local agent (full features, recommended):
CastingController(#) runs as a small local daemon (FastAPI + WebSocket) on the user's PC / Raspberry Pi / home server.HTTPServerThread:8766, the streamer servers :8768).Scope
CastingController(depends on #).Acceptance
Depends on the headless CastingController foundation (#).