Streamer Server (2) - V produkci

Používání Streamer Serveru postoupilo do fáze, kdy lze mluvit o zařazení do produkce, mezi ostatní aplikace. Stal se jednou ze základních aplikací 24/7 běžícího domácího serveru, kde svými funkcemi doplňuje aplikaci Tvheadend. Streamer Server je spouštěn automaticky při startu domácího serveru a bez problém běží již několik týdnů. Samozřejmě s občasným restartem, buď proto, že jeho funkce neustále vylepšuji a doplňuji a nebo proto, že rozšiřuji jeho databázi. Mezi funkce serveru sice patří reload hlavní databáze za plného běhu, ale často je, z testovacích důvodů, lepší ověřit, že nová databáze zvládne i případný restart bez vlivu na funkci serveru. Ostatně restart trvá jen pár vteřin, takže není třeba žádných zvláštních ohledů.

Nebudu se příliš rozepisovat, proto jen, více či méně, heslovitě zrekapituluji co se ve funkcích v samotném  serveru, ale i u jeho klientů, změnilo.

Nový typ providera

Rozhodl jsme se mezi providery, kteří poskytují přímé adresy streamů, přidat i providery OTT služeb. Ty jsem zatím přijímal prostřednictvím původního řešení, tedy dedikované IPTV Automatic Network a obvyklé sada scriptů. V rámci databáze providerů jsme přidal nový typ, k již existujícímu základnímu typu, které jsem pojmenovat jako URL, tedy přibyl typ providera OTT. Scripty jsem, pro použití serveru v rámci jednotného řešení pro všechny potenciální OTT providery, převedl do jednotné formy python třídy. Samozřejmě ze všemi obvyklými metodami login, register, refresh. Jen původní streamer teď chybí, protože ho nahradil společný streamer, tedy klient Stream Server-u. Zatím jsem takto integroval službu Sledovanitv.cz a OnePlay. Tady bych vyzdvihl nutnost přidání dalšího paralelního procesu, který případně (pokud je službou požadován) zajišťuje periodický refresh autorizace. Ale díky použití knihovny asyncio, na které jsou funkce serveru postavené, to mělo celkem jednoduché řešení.

K "piping-u" se ještě dostanu ve zvláštní kapitole. Co se týče výběru streamu, tak tam jsem implementoval možnost, že se streamy OTT služby nezúčastní výběru. Pokud existuje pro požadovanou "service" kanál v OTT službě, tak se použije rovnou a netestuje se jeho dostupnost. Je to samozřejmě volitelné parametrem. Stejně samozřejmé je i to, že v parametrech zpracování je tomuto "přeskočení" testování streamu OTT služby předřazeno testování limitu současně běžících streamů daného providera.

Klient v Kodi

Úkolem klienta v Kodi je poskytnout omezenou množinu funkcí, pomocí kterých lze aktuální nastavení Streamer Serveru ovládat z pohodlí obýváku s dálkovým ovladačem v ruce.




Piping

Přidání dalších zdrojů streamů si vyžádalo zobecnění procesu pipingu tak, aby bylo jednoduše definovatelné v rámci parametrů pro každého providera zvlášť. K dosavadní parametrům tedy pro každého providera přibyly dvě položky:

  • profile - který určuje jaká metod pipingu bude použita. Na výběr jsou (v současné chvíli):
    • ffmpeg
    • streamlink
    • streampeg - což je kombinace streamlink a ffmpeg
  • preset - definuje sadu parametrů pro použití v aplikacích (ffmpeg a/nebo streamlink). Sady parametrů, každá má svůj identifikátor, jsou pevně definované, v parametru preset jsou pouze odkazy příslušným identifikátorem
Jinak samozřejmě zůstává možnost pro každý stream (má vyšší prioritu) a/nebo pro každého providera definovat obsah parametrů:
  • user_agent
  • referer

Jen pro ilustraci, jak vypadá obsah preset pro streampeg profile. Tento se používá jako default pro piping kanálů Live TV Youtube.

STREAMPEG_PRESETS = {
    "default": {
        "options": [],
        "stream": [
            "--default-stream","best",
            "--hls-live-edge", "3"
        ],
        "in": [
            "-fflags", "+genpts"
        ],
        "out": [
            "-c", "copy",
            "-f", "mpegts",
            "-mpegts_flags", "+resend_headers",
            "-mpegts_service_type", "digital_tv"
        ]
    }
}

Příjem Youtube Live TV

Přidal jsem možnost jako zdroj kanálů použít Live TV kanály z Youtube. V první verzi jsem to řešil pomocí nového typu providera, ale nakonec se ukázalo, že to vůbec není třeba. Vše se podařilo vyřešit pipingem profilu streampeg a odpovídajícím presetem (viz výše).

Generace databáze

V tomto tématu není nic nového. Pro potřeby zahájení vývoje jsem si databázi vytvořil nejdříve ručně, později jsem pro její generaci vytvořil jednoduchý nástroj v excel. Měl jsme sice v plánu paralelně k serveru vytvářet i nástroj pro správu databáze, ale z toho zatím sešlo. Možná proto, že jsem v excel-u s pomocí několika maker získal poměrně jednoduchý a pro mé potřeby více než vyhovující nástroj. Dnes mám v databázi pro 350 kanálů z celkem 12 zdrojů více než 1200 streamů. Spravovat to v excel, kde mám vytvořená různá makra a dokážu z něj dostat celkem jednoduše finální json soubor databáze, je pro mě zatím stále ta nejjednodušší cesta.

Závěr

Několik týdnů používání ukázalo, že koncept řešení je správný. Překvapivě se také ukázalo, že nejvíce obávané zpoždění přepínání kanálů se nekoná. Hodně tomu napomáhá to, že se do permanentní cache ukládá poslední úspěšně vybraný stream, takže ve většině případů, je přepnutí skutečně bleskurychlé, protože se zdroj streamu nemění. Dalším pozitivním aspektem je, že jsem se dost věnoval optimalizaci parametrů ffmpeg, případně streamlink, pro jednotlivé zdroje. V důsledku toho je piping vždy, i díky existenci profile a preset nastavení, jednoduše nastavitelný na míru každému zdroji zvlášť.

Je tady samozřejmě ještě velký prostor pro zlepšení funkce. Asi nejzásadnější je chování streamů některých služeb právě při změně zdroje. Sice k němu dochází málokdy, ale když, tak u některých zdrojů to vede k nepříjemným projevům. V extrému až takovým, že se stream například spustí bez videa a je třeba přehrávání zastavit a znova spustit. Proč se to děje, to je dílem důsledek specifického fungování Tvheadend, a dílem toho, jak některé zdroje při zahájení streamování pracují se skladbou  obsahu streamu. Audio se ve streamu objeví hned, ale video až po nějakém čase. Jak z toho ven už vím, ale bude to znamenat přidat do logiky přepínání kanálů ošetření případu, kdy dojde ke změně zdroje streamu mezi konkrétními providery a podle toho pak vybrat odpovídající preset. Preset tedy nebude jen statický parametr pro daného providera, což jeho roli v logice řešení zásadně mění.

A na úplný závěr úvaha o možném dalším rozšíření použití. Už jsme se o tom myslím zmiňoval. Nabízí se samozřejmě možnost využít Streamer Server i pro použití jako zdroje Live TV v Kodi. Je to řešitelné a pokud o to někdo projeví zájem, budu o tom uvažovat. Je tu ale několik klíčových aspektů, které jsou pro způsob řešení určující:

  1. Asi nejjednodušší a nejrychlejší způsob řešení je vytvořit jednoduchý doplněk, který bude fungovat jako klient Streamer Server-u na socket api. Obsahem playlistu pak bude volání tohoto doplňku.
  2. Systémově a koncepčně lepší bude vytvořit další "prezentační" vrstvu v samotném serveru. Tzn. přidat další typ api k již existujícímu socket api, v toto případě tedy web server api. Koncepce řešení serveru s tím počítá. V podstatě je přidání další vrstvy velmi jednoduchá operace. Tedy až na to, obsluhu tohoto api napsat. Ale ani to není nic neřešitelného. V tomto případě bude obsahem playlistu webová (lokální) adresa.
Ale úvaha o využití v Kodi samozřejmě pootevírá další téma. A to je archiv Live TV. Tady to už je o chlup složitější, hlavně proto, že ne pro všechny zdroje daného kanálu bude ten archiv k dispozici a když ano, tak nemusí mít vždy stejný formát a logiku volby. Ale řešitelné to samozřejmě bude. Pouštět se do toho ale budu až v okamžiku, kdy to bude mít nějakou perspektivu použití. Tady bude hrát roli i to, jak se nakonec usadí možnost prezentace a publikování. Já sice uvažuji o vlastním Kodi repozitáři, ale moc se mi do toho nechce. Po zkušenostech s fórem xbmc-kodi.cz se už nechci na nějakou platformu příliš vázat. Na druhou stranu, když už mé výtvory popisuji tady na blogu, asi by bylo logické je i publikovat, resp. poskytnout i ostatním. Bez toho to totiž moc smysl nedává...

Předcházející díl: Streamer Server (1) - Úvod

Komentáře