Streamer Server (1) - Úvod
Popisuji jeden z mých zásadních projektů poslední doby, s jehož pomocí jsem se rozhodl vyřešit nepříliš šťastně řešené funkce aplikace Tvheadend v případech, kdy pro příjem streamů TV vysílání mám k dispozici více zdrojů. Jak se dočtete dále, aplikace Tvheadend to sice nějak dokáže řešit, ale ne vždy tak, jak by bylo třeba. Proto vznikla aplikace Streamer Server, která je vlastně centrem jakéhosi "mini ekosystému" správy zdrojů TV vysílání. Protože jde o poměrně komplexní a mimochodem stále ještě koncepčně neuzavřené řešení, půjde o seriál. Dnes tedy zatím první díl z několika. Kolik jich nakonec bude, to si teď odhadnout netroufám.
Kromě vlastního Kodi provozuji i aplikaci Tvheadend. Ta se zmíněným Kodi, které máme instalované na několika strojích (o tom někdy příště), tvoří základ našeho domácího setupu. O Tvheadend by se, podobně jako o Kodi, dalo psát do nekonečna, a z různých úhlů pohledu i míry detailů, a já se tomu samozřejmě nevyhnu. Dnes se ale zaměřím na jeden zcela konkrétní, snad až speciální, aspekt jeho používání. Na příjem TV vysílání prostřednictvím IPTV. A tady bych měl odbočit. Někdo po přečtení příspěvku namítne, že se o IPTV, v jednom z možných smyslů slova pro toto označení, nejedná. Ale to dnes řešit nebudu, na to si teď v hlavě připravuji jedno z prvních témat do rubriky Co je..., kterou bych rád brzy otevřel.
Kdo používá Tvheadend, tak se s tím určitě už setkal. Představte si situaci, kdy pro jeden (nebo i více) kanálů s TV vysíláním máte k dispozici více možných zdrojů. A ne všechny jsou stabilní, některé občas a na čas (nebo i navždy) vypadnou, což je právě ten důvod, proč jich člověk (tedy těch zdrojů) mívá více.
Východiska a zadání
Tvheadend má funkci, která umožňuje, pokud máme k dispozici pro jeden kanál více možných zdrojů, zajistit jejich přepínání. To se děje podle nastavených priorit a podle toho, který zdroj je v dané chvíli k dispozici. Je to hezká funkce, ale je s ní jedna potíž. Pokud je zdrojem vysílání IPTV, tak ona logika přepínání nefunguje. Je-li zdrojem vysílání např. DVB přijímač a dojde-li ke ztrátě signálu, Tvheadend umí přepnout na příjem služby stejného kanálu s nižší prioritou. Je-li ale zdrojem vysílání IPTV, tak pokud při spuštění streamu zdroj není k dispozici, tak žádnému přepnutí nedojde. A to je, v případě, že pro daný kanál máte takových zdrojů více, škoda. Po sérii neúspěšných pokusů, jak takové fallback přepnutí zajistit v rámci nativních funkcí Tvheadend, jsem si připravil následující koncept:
- všechny IPTV zdroje (rozumějte primárně url adresy, ale může to být i jinak - viz dále) budou uloženy v jedné společné databázi. Ta bude organizovaná podle kanálů, resp. služeb/service, které pro tyto kanály zajišťuj příslušný zdroj streamu a podle providerů, ve smyslu poskytovatelů obsahu. Provider tedy může být:
- skupina url adres streamů pro skupinu kanálů - v tomto případě je obsahem databáze přímo adresa streamu,
- poskytovatel OTT služeb - v tomto případě je obsahem databáze identifikace (parametr) pro třídu (python) zajišťující obsluhu pro danou OTT službu. Toto plánuji až ve druhé etapě, tedy až ve chvíli kdy vyřeším logiku základních funkcí. Půjde v podstatě pouze o použití mých dosavadních řešení pro příjem OTT služeb, které jsem používal dosud. V podstatě mám k dispozici scripty pro většinu českých OTT služeb, vyjma těch, které používají nějak restrikce (např. Skylink) nebo mají pouze streamy s DRM.
- databázi bude využívat serverová aplikace (říkejme ji dále server) s následujícími funkcemi:
- pokud sever přijme od klienta požadavek na stream pro danou službu/service, vyhledá pro danou službu všechny dostupné streamy,
- vybrané streamy otestuje a adresu prvního, který bude dostupný, vrátí jako platný stream pro danou službu.
- aplikace bude pracovat jako dvojice klient - server, běžící na stejném stroji jako Tvheadend:
- server jak daemon spouštěný při startu systému,
- klient, jako script typu streamer, spouštěný metodou pipe://, s parametrem název služby/service,
- propojení mezi klient a server bude zajištěno prostřednictvím socket,
- mezi funkce serveru, kromě výše uvedeného, bude patřit také:
- cache, do které se pro každou službu/service ukládá adresa posledního pozitivně otestovaný a vybraný stream - stream z cache se při následujícím testu vybere jak první,
- blacklist, do kterého se na nastavenou dobu ukládají negativně otestovaný stream - stream uložený do blacklist-u se při testech ignoruje.
- testování a streamu může probíhat volitelně, buď prostřednictvím aplikace curl nebo ffprobe.
V současné chvíli mám za sebou testování první funkční verze. V rámci zpracování aktuálně dostupných zdrojů mám definováno celkem 6 poskytovatelů, kteří mi dohromady poskytují zdroje pro celkem 224 kanálů. Celkový počet streamů je v současné chvíli 430.
Databáze streamů je generovaná jako soubor json typu dictionary, který si server načte při svém spuštění. Klíčem je název služby/service. Správa databáze je možná jednoduše offline a to tak, že se upraví soubor json. Poté je možné serveru poslat přes socket povel reload, na základě kterého server novou databázi z upraveného souboru načte. Vlastní řešení používá knihovnu asyncio, která umožní psát ty části kódu, ve kterých se často vyskytuje čekání na I/O operace, efektivně. V tomto případě, kdy nejdelší zpoždění je dáno odezvou na příslušný request (curl nebo ffprobe), to umožňuje optimalizovat provádění kódu poměrně jednoduchým způsobem. Výsledkem je, že při použití curl se doba výběru streamu pohybuje v řádech nízkých desetin sekundy, ffprobe je maximálně o jeden řád pomalejší. Proto zatím předpokládám preferovaně používat curl. Výběr způsobu testování bude ostatně jeden z dalších funkcí, kterou plánuji do serverová části doplnit.
V Tvheadend je pak vytvořena jedna IPTV Automatic Network síť, s jedním playlistem. Aby se zjednodušil proces scanování, je možné klientskou aplikaci streamer přepnout do SCAN modu, ve kterém místo skutečných streamů posílá aplikace do Tvheadend streamy generované lokálně v aplikaci. Scanování sítě tak vůbec nezatěžuje zdroje streamů.
V dalším pokračování se zaměřím na specifika řešení funkcí serverové části.
Následující díl: Streamer Server (2) - V produkci


Komentáře
Okomentovat