No description
  • Python 52.1%
  • Shell 21.9%
  • HTML 15.5%
  • JavaScript 8.6%
  • Dockerfile 1.8%
  • Other 0.1%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-09-30 20:27:40 +02:00
browser-extension Initial TV Distro sources 2026-09-28 20:14:46 +02:00
installer Make storage selection interactive 2026-09-30 20:27:40 +02:00
static Initial TV Distro sources 2026-09-28 20:14:46 +02:00
templates Initial TV Distro sources 2026-09-28 20:14:46 +02:00
tests Initial TV Distro sources 2026-09-28 20:14:46 +02:00
.dockerignore Initial TV Distro sources 2026-09-28 20:14:46 +02:00
.gitignore Initial TV Distro sources 2026-09-28 20:14:46 +02:00
99-tv-remote.rules Initial TV Distro sources 2026-09-28 20:14:46 +02:00
app.py Initial TV Distro sources 2026-09-28 20:14:46 +02:00
compose.yml Initial TV Distro sources 2026-09-28 20:14:46 +02:00
deploy.sh Initial TV Distro sources 2026-09-28 20:14:46 +02:00
Dockerfile Initial TV Distro sources 2026-09-28 20:14:46 +02:00
firefox-policy.json Initial TV Distro sources 2026-09-28 20:14:46 +02:00
launcher.py Initial TV Distro sources 2026-09-28 20:14:46 +02:00
README.md Add key-free ISO release build 2026-09-28 21:31:46 +02:00
remote-hotkey.py Initial TV Distro sources 2026-09-28 20:14:46 +02:00
requirements.txt Initial TV Distro sources 2026-09-28 20:14:46 +02:00
run.py Initial TV Distro sources 2026-09-28 20:14:46 +02:00
site_registry.py Initial TV Distro sources 2026-09-28 20:14:46 +02:00
start-firefox.sh Initial TV Distro sources 2026-09-28 20:14:46 +02:00
TV Hub Apps.desktop Initial TV Distro sources 2026-09-28 20:14:46 +02:00
TV Hub.desktop Initial TV Distro sources 2026-09-28 20:14:46 +02:00
tv-hub-remote.service Initial TV Distro sources 2026-09-28 20:14:46 +02:00
tv-hub.container Initial TV Distro sources 2026-09-28 20:14:46 +02:00

DISCLAIMER

This project was AI assisted, if you don't like that, don't use it. The VTM GO, Play, VRT MAX, Floatplane and YouTube websites are never altered; the extension making them controllable with a remote runs completely local. The included streaming tiles on the UI are merely links to the respective websites, nothing more. I am in no way affiliated with DPG Media, VRT or Play media.

TV Hub

A Python TV launcher with a containerized Flask UI, containerized official Jellyfin Media Player and Firefox ESR clients, and a standard-library host-side launcher bridge. Launches websites for respective services using Firefox ESR client with self written extension to activate the remote control friendly controls. Long press esc shows an 'Exit to TV Hub' overlay in the web app, clicking yes goes back to the TV Hub. This is a mapping based on my particular remote. The apps added are also based on my personal usage. I just put the source here so anyone can use this freely if they wish to break free of their TV (or android tv/apple tv) spyware.

Add A Site On The TV

From Plasma Bigscreen's home screen, open Manage Web Apps. Enter an app name and its HTTPS start URL. The URL's hostname is automatically authorized for remote navigation; add any additional hostnames the site uses (for example, an identity-provider hostname) as comma-separated domains. Save the app and close settings to return to Bigscreen. The custom site is added to the Bigscreen home screen and launches in its own Podman Firefox profile. Changes persist across container image updates.

The generic extension provides arrow-key navigation, Enter-to-select, Back, and return-to-hub behavior. It is scoped to the existing built-in streaming domains and the exact domains saved for custom apps (including their subdomains); it does not run on every website. The regenerated extension is synced into Firefox profiles at launch, so newly added/changed domains take effect the next time Firefox opens a site. If a site needs its own navigation behavior, that still requires an extension code change.

Custom app definitions are stored in /home/tv/.local/share/tv-hub/custom-apps.json on the TV, and are mounted into the container. The Quadlet also shares the host's Bigscreen favorites configuration and application-entry directory with the container so it can add/remove launcher tiles. The installer ISO bundles this registry so custom apps survive reinstalling the appliance.

Run From The Registry

The published image is:

forgejo.vosjes.cloud/yarrith/tv-hub-podman:latest

On a logged-in Wayland desktop with Podman and /dev/dri available, run the UI container with:

podman run --rm --name tv-hub-ui \
  --network host \
  --shm-size 1g \
  -e WAYLAND_DISPLAY="${WAYLAND_DISPLAY:-wayland-0}" \
  -e XDG_RUNTIME_DIR="${XDG_RUNTIME_DIR:-/run/user/$(id -u)}" \
  -e DBUS_SESSION_BUS_ADDRESS="${DBUS_SESSION_BUS_ADDRESS:-unix:path=/run/user/$(id -u)/bus}" \
  -e QT_QPA_PLATFORM=wayland \
  -e QTWEBENGINE_DISABLE_SANDBOX=1 \
  -v "${XDG_RUNTIME_DIR:-/run/user/$(id -u)}:${XDG_RUNTIME_DIR:-/run/user/$(id -u)}" \
  -v tv-hub-jellyfin-config:/root/.config \
  -v tv-hub-jellyfin-data:/root/.local/share \
  --device /dev/dri:/dev/dri \
  forgejo.vosjes.cloud/yarrith/tv-hub-podman:latest

This publishes the hub at http://127.0.0.1:8080. The named volumes hold Jellyfin settings and browser profiles; they are created on the machine and are not part of the image. For the complete desktop experience, including the fullscreen hub browser and the localhost launch bridge, use the checkout-based python3 run.py flow below.

Autostart With Quadlet

Install the rootless Quadlet unit and enable it for the logged-in desktop user:

podman pull forgejo.vosjes.cloud/yarrith/tv-hub-podman:latest
mkdir -p ~/.config/containers/systemd
cp tv-hub.container ~/.config/containers/systemd/tv-hub.container
systemctl --user daemon-reload
systemctl --user enable --now tv-hub.service

The unit starts the registry image with the current user's Wayland runtime, D-Bus session, GPU, shared memory, and named persistent volumes. The image provides its own launch and return-home endpoints, so this deployment does not need the checkout-based host launcher bridge. It is enabled only after graphical-session.target is active, so it cannot block graphical login. Image pulls are deliberately not performed by the login service; pull updates manually before restarting it. Check it with:

systemctl --user status tv-hub.service

To update the image:

podman pull forgejo.vosjes.cloud/yarrith/tv-hub-podman:latest
systemctl --user restart tv-hub.service

After the service is running, install TV Hub Apps.desktop into ~/.local/share/applications/ or copy it there with:

cp "TV Hub Apps.desktop" ~/.local/share/applications/

Launching TV Hub Apps opens Firefox in kiosk mode at http://127.0.0.1:8080.