# Živá TV z antény do Plexu: Tvheadend + Antennas na Raspberry Pi

> Zdroj: https://www.elvisek.cz/2026/05/ziva-tv-tvheadend-plex-raspberry-pi/ · Autor: Claude Laura · Publikováno: 15. 5. 2026 · Rubrika: Raspberry Pi

## Proč to celé

Pozemní DVB-T2 vysílání se dá na Raspberry Pi chytat a posílat do Plexu jako plnohodnotná živá TV i s programovým průvodcem. Jádrem je Tvheadend, který obsluhuje tuner, a Plex, který z toho dělá pohodlné rozhraní na televizi, mobilu i v prohlížeči.

Tvheadend má sice vestavěnou emulaci HDHomeRun, ale v praxi je nestabilní. Plex na televizi občas hlásil „Nelze naladit kanál“ a přehrávání prostě nenaběhlo. Řešením se ukázal malý proxy kontejner **Antennas** a hlavně důkladné vyladění Tvheadendu, který tuner zbytečně vytěžoval skenováním na pozadí.

Navazuju tím na starší článek [RasPi – IPTV server](https://www.elvisek.cz/2020/10/raspi-iptv-server/) z roku 2020. Tam Tvheadend běžel přímo v systému a na televizi se koukalo přes Kodi nebo VLC. Teď běží v Dockeru a všechno jde přes Plex.

V článku projdu celou cestu: od přípravy Raspberry Pi přes Docker, kritická nastavení Tvheadendu, napojení na Plex až po problémy, na které jsem při stavbě narazil. Na konci je bonus o přechodu z RPi 4 na RPi 5.

## Co budete potřebovat

Stačí Raspberry Pi s TV HATem, anténa, Docker a Plex Media Server s Plex Pass.

| Komponenta | Co používám |
| --- | --- |
| Počítač | Raspberry Pi 5 (funguje i RPi 4) |
| Tuner | Sony CXD2880 DVB-T/T2 HAT (SPI, 1 tuner) |
| Úložiště | SD karta 16 GB+ |
| OS | Raspberry Pi OS 64-bit, Debian 13 Trixie |
| Kontejnery | Docker + Docker Compose |
| Plex | Plex Media Server s Plex Pass (Live TV & DVR) |
| Nahrávky | NAS přes NFS (volitelné) |

V příkladech používám tuto síť: Raspberry Pi na `10.100.10.21`, NAS s Plexem na `10.100.10.11`. Adresy si upravte podle sebe.

## Jak to do sebe zapadá

Tuner obsluhuje Tvheadend, Antennas mu dělá tlumočníka a Plex si myslí, že mluví s fyzickým HDHomeRun.

```text
            [ Anténa DVB-T2 ]
                    │
  ┌─────────────────┼──── Raspberry Pi 5 · 10.100.10.21 · Docker ──┐
  │                 ▼                                              │
  │       [ Sony CXD2880 HAT ]                                     │
  │       SPI, 1 tuner, /dev/dvb/adapter0                          │
  │                 │                                              │
  │                 ▼                                              │
  │       [ Tvheadend :9981 ] ──── API ────► [ Antennas :5004 ]    │
  │       ladí multiplexy,                   překládá API          │
  │       profil pass, XMLTV EPG             na HDHomeRun          │
  └─────────────────┼──────────────────────────────┼───────────────┘
                    │ stream MPEG-TS + XMLTV EPG   │ lineup přes HDHR API
                    ▼                              │
       [ Plex Media Server ] ◄─────────────────────┘
       Synology NAS · 10.100.10.11
                    │
                    ▼
             [ Klienti ]
       TV: Direct Play i HEVC
       prohlížeč: HEVC se transkóduje
```

Antennas Plexu předává jen seznam kanálů. Samotný stream si Plex stahuje přímo z Tvheadendu na portu 9981, proto musí mít uživatel `plex` právo streamovat.

## Příprava Raspberry Pi

Na čistém Raspberry Pi OS stačí aktualizace, statická IP, Docker a ověření, že systém vidí tuner.

### Systém a statická IP

OS nahrajte přes Raspberry Pi Imager, kde rovnou nastavíte hostname, uživatele a SSH. Trixie spravuje síť přes NetworkManager:

```bash
sudo apt update && sudo apt upgrade -y

# název připojení zjistíte přes: nmcli connection show
sudo nmcli connection modify "Wired connection 1" \
  ipv4.method manual \
  ipv4.addresses 10.100.10.21/24 \
  ipv4.gateway 10.100.10.1 \
  ipv4.dns "10.100.10.1 8.8.8.8"
sudo nmcli connection down "Wired connection 1" && sudo nmcli connection up "Wired connection 1"
```

Po změně IP spadne SSH relace, připojte se na novou adresu.

### Ověření TV HATu

Sony CXD2880 je připojený přes SPI. Na kernelu 6.12 se driver načte sám, žádný overlay v `config.txt` jsem nepotřeboval, a to ani na RPi 5 s novým čipem RP1.

```bash
dmesg | grep -iE "cxd2880|dvb"
ls -la /dev/dvb/adapter0/
```

Ve výpisu musí být `Sony CXD2880 has successfully attached` a v adresáři zařízení `frontend0`, `demux0` a `dvr0`.

### Docker

```bash
curl -fsSL https://get.docker.com | sudo sh
sudo usermod -aG docker $USER
newgrp docker
```

### NFS mount na NAS (volitelné)

Nahrávky a zálohy ukládám na NAS. Volby `nofail` a `_netdev` zajistí, že Pi nabootuje i bez dostupného NASu.

```bash
sudo apt install -y nfs-common
sudo mkdir -p /mnt/server
echo "10.100.10.11:/volume1/NAS-DOWNLOAD /mnt/server nfs vers=3,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,nofail,_netdev 0 0" | sudo tee -a /etc/fstab
sudo mount -a
```

## Docker Compose: Tvheadend a Antennas

Oba kontejnery běží v jednom `docker-compose.yml` v režimu `host`, aby fungovalo SSDP a porty byly přímo na IP Raspberry Pi.

Soubor `/opt/docker/docker-compose.yml`:

```yaml
services:
  tvheadend:
    image: lscr.io/linuxserver/tvheadend:latest
    container_name: tvheadend
    network_mode: host
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Europe/Prague
    volumes:
      - /opt/docker/tvheadend/config:/config
      - /mnt/server:/recordings
    devices:
      - /dev/dvb:/dev/dvb
      - /dev/dri:/dev/dri
    restart: unless-stopped

  antennas:
    image: thejf/antennas:latest
    container_name: antennas
    network_mode: host
    environment:
      - TVHEADEND_URL=http://plex:HESLO@127.0.0.1:9981
      - ANTENNAS_URL=http://10.100.10.21:5004
      - TUNER_COUNT=1
      - DEVICE_UUID=2f70c0d7-90a3-4429-8275-cbeeee9cd605
    restart: unless-stopped
```

| Parametr | Význam |
| --- | --- |
| `PUID` / `PGID` | ID uživatele, výstup `id -u` a `id -g` |
| `TVHEADEND_URL` | přístup Antennas do Tvheadendu (uživatel `plex`) |
| `ANTENNAS_URL` | adresa, kterou Antennas hlásí Plexu |
| `TUNER_COUNT` | počet fyzických tunerů, u CXD2880 HATu 1 |
| `DEVICE_UUID` | libovolné platné UUID, Plex podle něj zařízení pozná |

`TUNER_COUNT` nenastavujte vyšší, než kolik tunerů opravdu máte. Plex by pak zkoušel sledovat a nahrávat paralelně a druhý požadavek by skončil chybou.

```bash
cd /opt/docker
docker compose up -d
docker logs tvheadend --tail 50
```

Web Tvheadendu najdete na `http://10.100.10.21:9981`, HDHomeRun API Antennas na `http://10.100.10.21:5004/discover.json`.

## Nastavení Tvheadendu

Klíčem ke stabilitě je vypnout veškeré skenování na pozadí. S jedním tunerem každý sken obsadí tuner právě ve chvíli, kdy si o kanál řekne Plex, a výsledkem je „No input detected“.

U mě skenovaly hned čtyři vrstvy současně a v logu přibýval nový sken každých 10 sekund. Každou je potřeba vypnout zvlášť, protože jsou na různých místech konfigurace.

### DVB-T síť

*Configuration → DVB Inputs → Networks → DVB-T Network*

| Parametr | Hodnota |
| --- | --- |
| Network discovery | Disable |
| Skip startup scan | zapnuto |
| Idle scan muxes | vypnuto |

Po prvotním naskenování smažte muxy, které trvale hlásí FAIL. Auto-discovery mi jich nasbíral 80, reálně funguje 7.

![Seznam muxů v Tvheadendu: sedm frekvencí DVB-T, všechny ve stavu IDLE](https://www.elvisek.cz/wp-content/uploads/2026/10/tvheadend-muxy.webp)

*Po úklidu zůstalo sedm muxů, skenování je v klidu (IDLE)*

### TV adaptér

*Configuration → DVB Inputs → TV adapters → Sony CXD2880*

| Parametr | Hodnota |
| --- | --- |
| Idle scan | vypnuto |
| Initial scan | vypnuto |
| LNA | zapnuto |
| # tune repeats | 2 |
| Scan grace period | 15 s |
| Streaming priority | 10 |

Pozor: `Idle scan` na adaptéru je jiné nastavení než `Idle scan muxes` na síti. Vypnout je nutné obě.

![Nastavení TV adaptéru Sony CXD2880 v Tvheadendu](https://www.elvisek.cz/wp-content/uploads/2026/10/tvheadend-adapter-cxd2880.webp)

*Adaptér CXD2880: LNA zapnuté, Initial scan a Idle scan vypnuté, streaming priority 10*

### Stream profil `pass`

*Configuration → Stream → Stream Profiles → pass*

| Parametr | Hodnota |
| --- | --- |
| Data start timeout | 15 s |
| Restart on error | zapnuto |
| Default priority | High |
| Rewrite PMT, PAT, SDT, NIT, EIT | zapnuto |

Profil `pass` posílá MPEG-TS beze změny a přesně ten chce Plex. Profily `webtv-*` a `matroska` transkódují na Raspberry Pi, pro Plex je nepotřebujete a můžete je vypnout.

![Stream profil pass v Tvheadendu](https://www.elvisek.cz/wp-content/uploads/2026/10/tvheadend-profil-pass.webp)

*Profil pass: start timeout 15 s, priorita High, restart při chybě a přepis tabulek*

### EPG

*Configuration → Channel / EPG → EPG Grabber*

- OTA cron stačí jednou denně v noci: `4 3 * * *`
- Vypněte „Force initial EPG grab at start-up“ u OTA i interních grabberů
- Interní grabber cron nechte prázdný, pokud nepoužíváte externí XMLTV

## Uživatelé a EPG pro Plex

Potřebujete dva účty: `admin` pro správu a `plex` jen pro streaming, který používá Antennas.

*Configuration → Users → Access Entries* a *Passwords*

| Účet | Admin | Streaming | Web interface | Network prefix |
| --- | --- | --- | --- | --- |
| `admin` | ano | ano | ano | `0.0.0.0/0` |
| `plex` | ne | ano + advanced | ne | `10.100.0.0/16` |

Nejdřív vytvořte `admin` a ověřte přihlášení v anonymním okně. Teprve pak omezte výchozí přístup, jinak se snadno zamknete.

### Programový průvodce přes XMLTV

Tvheadend vystavuje EPG na adrese `http://10.100.10.21:9981/xmltv/channels`. Plex ji umí načíst jako vlastní průvodce.

Zádrhel: Tvheadend standardně vyžaduje Digest autentizaci a Plex umí v URL jen Basic (`user:heslo@host`). Výsledkem je obecná chyba „Při komunikaci s poskytovatelem nastala chyba“.

Řešením je wildcard přístup (uživatel ``) jen s právem *Web interface, omezený na lokální síť. EPG pak Plex načte z URL bez hesla. Ověřit to jde jednoduše:

```bash
curl -s http://10.100.10.21:9981/xmltv/channels | head -20
```

Má vrátit XML začínající `<?xml` se seznamem kanálů.

![Programový průvodce v Tvheadendu se seznamem pořadů](https://www.elvisek.cz/wp-content/uploads/2026/10/tvheadend-epg.webp)

*Programový průvodce v Tvheadendu, odtud si ho přes XMLTV bere Plex*

## Napojení na Plex

Plex přidá Antennas jako tuner HDHomeRun, stačí zadat IP a port ručně.

1. *Nastavení → Živá TV a DVR → Nastavit Plex DVR*
2. Automatické hledání v Dockeru často nic nenajde, klikněte na „Nevidíte svůj HDHomeRun?“
3. Zadejte `10.100.10.21:5004`, Plex najde „Silicondust HDHomeRun (Antennas)“
4. Jako průvodce zvolte XMLTV s adresou `http://10.100.10.21:9981/xmltv/channels` a jazykem čeština
5. Vyberte kanály, které chcete mít v Plexu

### Kvalita překódování

*Nastavení → Živá TV a DVR → zařízení → Nastavení*

Kvalitu překódování nastavte na **Původní formát**. Při volbě „Nejvyšší kvalita“ Plex transkóduje každý stream a na slabším serveru to selže.

V nastavení transkodéru Plex serveru doporučuji:

| Parametr | Hodnota |
| --- | --- |
| Kvalita převodníku | Preferovat vyšší rychlost kódování |
| Hardwarová akcelerace | zapnuto |
| HW dekódování videa | zapnuto |
| Dočasná složka pro překódování | složka, do které má Plex právo zápisu |

U poslední položky jsem na Synology narazil na `Permission denied`. Plex v takovém případě tiše padá na software a transkódování nestíhá.

## HEVC: proč to na televizi jede a v prohlížeči ne

Kanály skupiny Nova na MUX 24 vysílají v HEVC (H.265). Televize je přehraje přímo, prohlížeč je musí nechat transkódovat a to je pro starší server těžké sousto.

| Klient | HEVC | Výsledek |
| --- | --- | --- |
| Apple TV, Samsung, LG, Android TV | nativní dekodér | Direct Play, bez transkódování |
| Webový prohlížeč | nepodporuje | Plex transkóduje HEVC → H.264 |

V logu Plexu se problém pozná podle hlášek `PPS id out of range` a podle `fallback to software decoding`. Můj Synology DS918+ má Intel Celeron J3455, jehož Quick Sync neumí dekódovat HEVC Main 10. Transkódování pak běží softwarově a v reálném čase nestíhá.

Pro živou TV na televizi to nevadí. Kdo chce sledovat i v prohlížeči, potřebuje Plex server s novějším Intel GPU (zhruba 10. generace a výš) nebo Apple Silicon. Výměna Raspberry Pi tady nepomůže, transkódování dělá Plex server, ne Pi.

## Časté problémy

Většinu potíží odhalí log Tvheadendu: `docker logs tvheadend -f --tail 50`.

| Příznak | Příčina | Řešení |
| --- | --- | --- |
| No input detected, Nelze naladit kanál | sken na pozadí drží tuner | vypnout všechny scan vrstvy |
| v logu `scan ... weight: 2` každých ~10 s | Idle scan na adaptéru nebo síti | Idle scan a Idle scan muxes vypnout |
| chyba poskytovatele u XMLTV v Plexu | Digest autentizace | wildcard přístup pro LAN, URL bez hesla |
| prázdný lineup v Antennas | špatné heslo v `TVHEADEND_URL` | ověřit uživatele `plex` |
| `PPS id out of range` v Plexu | HEVC v prohlížeči | sledovat na TV nebo silnější Plex server |
| `hdhomerun server not enabled` | Plex zkouší starou emulaci | ignorovat, nebo HDHR zařízení v Plexu přidat znovu |

Užitečné příkazy pro diagnostiku:

```bash
# Je tuner vidět?
dmesg | grep -iE "cxd2880|dvb"

# Co Antennas posílá Plexu
curl -s http://10.100.10.21:5004/lineup.json | python3 -m json.tool | head -30

# Jaké stream profily klienti skutečně používají
docker logs tvheadend 2>&1 | grep -oP 'profile="[^"]+"' | sort | uniq -c
```

## Bonus: přechod z RPi 4 na RPi 5

Celá migrace zabrala zhruba hodinu a Plex si nového hardwaru ani nevšiml. Pomohlo, že nové Pi dostalo stejnou IP adresu i stejný config.

1. Na starém Pi zastavit kontejnery a zazálohovat `/opt/docker` na NAS
2. Na RPi 5 nahrát čistý Trixie, nastavit stejnou statickou IP, Docker a NFS
3. Nasadit TV HAT a ověřit `/dev/dvb/adapter0`
4. Rozbalit zálohu a spustit `docker compose up -d`

```bash
# záloha (na starém Pi)
cd /opt/docker && docker compose down
sudo tar -czf /mnt/server/backup/opt-docker-$(date +%F).tar.gz \
  --exclude='tvheadend/config/epgdb*' \
  --exclude='tvheadend/config/imagecache' \
  --exclude='tvheadend/config/backup' \
  -C /opt docker

# obnova (na novém Pi)
sudo tar -xzf /mnt/server/backup/opt-docker-DATUM.tar.gz -C /opt
cd /opt/docker && docker compose up -d
```

Obával jsem se, že SPI HAT bude na RPi 5 kvůli novému čipu RP1 potřebovat vlastní overlay. Nepotřeboval, kernel 6.12 ho rozpoznal sám.

## Závěr

Výsledkem je stabilní živá TV v Plexu: kanál naběhne do dvou sekund a přepínání mezi multiplexy funguje bez výpadků. Největší ponaučení: problém nebyl v Plexu ani v hardwaru, ale ve skenování, které Tvheadend tiše provozoval na pozadí. Pokud vám živá TV „občas nejede“, začněte právě tam.
