×

📺 IPTV

B2C · Xtream · Reseller

IPTV Správa používateľov

Archívne ukladacie vrstvy (Storage Tiers)

Trojvrstvový archívny systém pre 500+ súbežných klientov. Konfigurácia v Config > Storage > Storage Tiers. Každá vrstva má nezávislý životný cyklus, výpočet kapacity a fallback správanie.

Kodér

Zapisovacia buffer

2h hot window (NVMe alebo tmpfs)

→ mirror (kontinuálne)

HDD RAID 5

50 TB, retencia 14 dní

→ prefetch na požiadanie

Cache pre prehrávanie

1 TB warm cache, 500+ klientov

Klienti

Mirror, nie presun

Segmenty staršie ako mirror_min_age_minutes sa KOPÍRUJÚ do RAID kontinuálne. Write_buffer drží 2h hot window aby rewind-na-nedávne playback zostal na rýchlom úložisku. Až po evict_age_minutes (a iba pri overenom mirror-i) sa segmenty mažú z write_buffer. RAID má vždy dlhodobú kópiu — žiadne hodinové burst transfery.

Vrstva

Účel

Nastavenia

Zapisovacia buffer

Prijíma segmenty 24/7, drží 2h hot window pre rýchle rewind-na-nedávne playback, chráni RAID pred random IO. Device môže byť fyzická NVMe partícia (produkcia) alebo tmpfs (dev/test box bez fyzického NVMe — viď tmpfs sekciu nižšie).

device_path (block device alebo 'tmpfs'), tmpfs_size_pct (10-50% MemAvailable pri tmpfs), mirror_min_age_minutes, evict_age_minutes, flush_threshold_percent (trigger force flush)

HDD RAID archív

Dlhodobé úložisko pre plnú retenciu (default 14 dní). Prijíma kontinuálny mirror trickle z write_buffer — sekvenčný zápis, žiadne hodinové bursty. Prežije reboot. RAID prežije zlyhanie jedného disku.

retention_days, raid_device, nginx_location, min_free_percent

Playback Cache (voliteľná)

Read-side cache pre populárne súbory staršie ako 2h (napr. EPG catch-up). Naplňa sa z archívu na požiadanie po prekročení popularity prahu (3 hity / 5 min). Device môže byť NVMe alebo tmpfs.

prefetch_hours, max_sessions, eviction_policy (session/lru/fifo)

Výpočet kapacity

live writes × 2h = veľkosť write_buffer hot window. Príklad: 50 streamov × 8 Mbps × 2h ≈ 36 GB. Pridaj ~30% headroom pre mirror trickle backlog → ~50 GB write_buffer stačí na 50 streamov. RAID dimenzovaný pre plnú retenciu: 50 × 8 Mbps × 14 dní ≈ 6 TB.

Čítanie (tier-aware lookup)

Stream.dvr_file_path/2 prehľadáva write_buffer → playback_cache → archive v poradí. Segment v 2h hot window sa servuje z write_buffer pri native rýchlosti aj keď existuje aj na RAID. Nginx X-Accel-Redirect servuje súbory priamo bez Phoenix.

tmpfs virtuálny disk (dev/test)

Každá vrstva môže používať RAM-backed tmpfs virtuálny disk namiesto fyzického block device. Užitočné pre dev boxy bez voľného NVMe alebo pre ephemeral test prostredia. Storage Tier karta device dropdown obsahuje 'tmpfs (virtuálny disk z RAM)' option ktorý nahradí výber cesty zariadenia za percentuálny slider.

Veľkosť v % free RAM

Alokácia sa zadáva ako percento z MemAvailable (z /proc/meminfo) — krok 10, platné hodnoty 10/20/30/40/50. Hard floor 10% (validácia odmietne pod). Hard ceiling 50%. Default 30%. Pri 100 GB MemAvailable: 10% = 10 GB, 30% = 30 GB, 50% = 50 GB. Pri zmene slidera + Save sa veľkosť prepočíta a tmpfs sa live remountuje.

Bezpečnostný obmedzovač OOM

Ak by vypočítaný target prekročil 60% aktuálnej MemAvailable, mount je odmietnutý a vrstva zostane offline (Stream.archive_path padá na ďalšiu zdravú vrstvu). Zabráni agresívnemu nastaveniu zabiť BEAM cez OOM. Guard beží pri boote aj pri každom Save v UI.

Reboot persistencia

tmpfs žije v RAM — akýkoľvek in-flight buffer obsah sa STRATÍ pri reštarte hostu. Fstab entry zapísaný pri provisioningu automaticky remountne prázdny tmpfs pri ďalšom boote, ale staré segmenty sa nevrátia. Mirror do archive pokračuje normálne pre všetko čo už bolo mirrorované pred reboot — stratí sa iba posledné nemirrované okno (typicky < mirror_min_age_minutes). Pre produkciu použi fyzický NVMe device; tmpfs je určený ako dev/test substitút.

Kedy použiť tmpfs

Použi tmpfs pre write_buffer keď: (a) dev/test box nemá voľný NVMe ale chceš celú DVR pipeline pre integration testing, (b) operator chce validovať mirror + archive správanie bez kúpy NVMe vopred, (c) ephemeral testing kde loss-on-reboot je akceptovateľný. Nepoužívaj tmpfs v produkcii — RAM je volatile a rádovo drahšia než NVMe per GB retencie.

Rýchlejší flush pre tmpfs

Keď je write tier tmpfs, StorageTierFlush používa tesnejšie defaults — mirror_min_age 2 min, evict_age 15 min (vs 5 min / 120 min pre fyzický NVMe). RAM je drahšia ako disk, takže rolling hot window sa drží menšie. Override cez MIRROR_MIN_AGE_MINUTES / EVICT_AGE_MINUTES env premenné ak treba.

Auto-Provisioning vrstiev & Safety

Vrstvy sa konfigurujú raz cez Config > Storage > Storage Tiers a provisionujú sa automaticky — žiadne manuálne mkfs/mount/fstab editovanie na hoste. StorageTier.ensure_all_provisioned/0 beží pri každom boote zo SystemInitializer a je idempotent: už-mountnuté vrstvy sa skipujú, chýbajúce devices sú no-op, tmpfs vrstvy sa čisto remountnú po reboote.

Predvolený boot seed

Pri prvom boote (žiadny write tier v DB) systém auto-vytvorí tmpfs-backed write tier s 30% MemAvailable alokáciou, mount point /mnt/nvme_write. Toto dáva funkčnú DVR pipeline out-of-the-box na akomkoľvek hoste s dostatočnou RAM. Operator môže neskôr prepnúť device na fyzický NVMe cez UI bez straty ostatných tier nastavení.

Zdravie & failover

Stream.archive_path/1 vracia prvú 'zdravú' vrstvu — write_buffer ak mounted+writable+free_pct nad safety floor, inak padá na archive (degraded mode). Safety floor 20% pre tmpfs (RAM-strict), 2% pre block devices. tier_health endpoint exposuje per-tier mounted/writable/free_pct pre monitoring.

Live zmena veľkosti

Zmena tmpfs_size_pct v UI triggerne umount + remount s novou veľkosťou pri Save. Aktívne DVR writes sú krátko pozastavené (mount transition < 1 s). Odporúčanie: meň tmpfs veľkosť iba pri nízkom DVR write rate, a zváž reštart streamov potom aby čisto vzali nový mount.

Základná URL pre IPTV

Polesa balíčkov

API balíkov

Pravidlá hesla

Reseller API

Nastavenia

Polia používateľa

Správa používateľov

IPTV správa používateľov

Základná URL — OSTV Player

Aplikácia OSTV Player umožňuje používateľom zmeniť base URL servera (API adresu). Táto funkcia je dostupná len pre používateľov s providerom nastaveným na root.

Dôvod: Zmena base URL je určená len pre administrátorov/root používateľov, aby mohli prepínať medzi servermi (napr. produkcia vs. testovanie). Bežní používatelia majú fixnú base URL a nemôžu ju zmeniť.

Polia používateľa

Balíčky API

Vráti zoznam všetkých aktívnych balíkov s cenami a fakturačnými obdobiami.

Zoznam management používateľov (resellerov / providerov).

Vráti zostatok kreditu pre konkrétneho management používateľa.

Polia balíka

Reseller API

API pre resellerov/providerov. Autorizácia: Authorization: Bearer mtk_... (token z Manage Users). Reseller vidí len vlastných klientov (owner_id).

Politika hesiel

Heslo je povinné pri vytváraní predplatiteľa. Pravidlá:

Minimálne 8 znakov

Aspoň 1 veľké písmeno (A-Z)

Aspoň 1 špeciálny znak (!@#$%^&* atď.)

Platí pre UI aj API. Pri update je heslo voliteľné, ale ak je zadané, musí spĺňať pravidlá.

Nastavenia

Auto-provisioning tierov &amp; bezpečnosť

Auto-detekcia kapacity + filesystému: keď sa z dropdownu vyberie voľné NVMe, kapacita (GB) sa načíta z lsblk -bn -o SIZE a aktuálny FS z blkid (s fallbackom na celý disk). Formulár zobrazí hodnoty read-only — žiadne ručné zadávanie, žiadne chyby.

Mechanizmus flush tierov — kontinuálny mirror

StorageTierFlush GenServer beží každých 60s. Namiesto čakania kým hour-dir „zostarne“ a presunie ho ako 5GB burst, priebežne odlieva segmenty na RAID a drží 2h hot okno na NVMe pre rýchle „nedávne pretočenie“. Dve fázy sú oddelené — kopírovanie a mazanie sú samostatné, overené operácie.

Prečo kontinuálny mirror je lepší než „čakaj 60min, dávkový presun“: (1) Záťaž RAID je rovnomerná — žiadne 5GB bursty na hraniciach hodín, len odlievanie 7MB segmentov; (2) Väčšina hot dát je už na RAID — disaster recovery stratí len posledné minúty; (3) Eviction je overený per-súbor — čiastočné zlyhanie mirroru sa zistí skôr než sa stratia NVMe dáta.

Bezpečnosť rozpracovaných segmentov: mirror berie len súbory staršie než MIRROR_MIN_AGE_MINUTES cez find -mmin +5. Segmentový súbor ktorý FFmpeg ešte zapisuje sa v zozname neobjaví — žiadna šanca na prenos čiastočného zápisu.

Ladenie per deployment (.env)

500–1000

Pravidlo dimenzovania:

DVR Preview kalendár

Záložka DVR Preview zobrazuje server-rendered kalendár ktorý zvýrazní len dni pre ktoré existujú nahrávky na disku. Sken beží cez každý tier (write_buffer + read_cache + archive + legacy), takže segment ktorý bol práve odliaty z NVMe na RAID zostáva viditeľný bez oneskorenia.

Dni s nahrávkami sú klikateľné (modré) — klik predvyplní datetime input daným dňom o 00:00; používateľ potom vyberie hodinu. Dni bez nahrávky sú stlmené a neaktívne.

Implementované v Stream.available_dvr_days/1 cez find -mindepth 4 -maxdepth 4 -type d na každom tier mounte; deduplikované naprieč tiermi (deň sa zobrazí raz aj keď má segmenty vo viacerých tieroch počas flush okna).

B2C prehrávač API

Prehľad

B2C (Business-to-Consumer) API poskytuje autentifikáciu a prístup k streamom pre koncové prehrávačové aplikácie. Používatelia sa autentifikujú menom a heslom a dostanú časovo obmedzený auth token pre nasledujúce požiadavky.

Autentifikácia

Autentifikácia používateľa a získanie auth_tokenu pre nasledujúce API volania.

Metóda

Koncový bod

Telo požiadavky

Parameter

Typ

Povinný

Popis

Áno

Prihlasovacie meno používateľa

Heslo používateľa

Príklad požiadavky

Polia odpovede

Úspešná odpoveď (200)

Šifrovaný autentifikačný token pre nasledujúce API volania

Dátum a čas expirácie tokenu vo formáte ISO 8601

Príklad úspešnej odpovede

Chybová odpoveď (403)

Popis chybovej správy

HTTP stavový kód

Príklad chybovej odpovede

Informácie o používateľovi

Získanie informácií o autentifikovanom používateľovi pomocou auth tokenu.

Polia odpovede

Používateľské meno autentifikovaného používateľa

Správa zo servera (prázdna ak žiadna)

Stav autentifikácie (1 = autentifikovaný)

Stav účtu: Active, Banned, Disabled, Trial

Dátum expirácie účtu (null ak neobmedzený)

Počet aktuálnych aktívnych pripojení

Dátum vytvorenia účtu vo formáte ISO 8601

Maximálny počet súčasných pripojení

Zoznam povolených výstupných formátov streamu

Názov providera vlastníka/resellera používateľa (null ak žiadny)

URL loga providera (null ak žiadne)

URL collapse loga providera 208x208 (null ak žiadne)

Aktuálny čas servera vo formáte ISO 8601

Príklad požiadavky

Kategórie

Získanie kategórií filtrovaných podľa typu. Dostupné typy: live (streamy), vod (filmy), series (seriály).

Typ kategórie: live, vod alebo series

ID kategórie ako reťazec

Zobrazovaný názov kategórie

ID rodičovskej kategórie (0 ak koreňová)

MD5 hash obsahu pre invalidáciu cache

Príklad požiadavky

Detail VOD

Získanie podrobných informácií o konkrétnej VOD položke vrátane metadát a odkazov na stream.

ID VOD streamu (UUID)

Polia objektu Info

URL obrázka obalu

TMDB identifikátor

URL obrázka pozadia

Žáner

Popis / dej

Herci

Hodnotenie (0-10)

Režisér

Dátum vydania

Dĺžka v sekundách

Dĺžka ako formátovaný reťazec

Pole ID kategórií

1 ak obsah pre dospelých, inak 0

Polia objektu VOD

ID VOD streamu

Názov VOD

Dátum pridania (ISO 8601)

URL odkazy na stream

Metadáta video/audio kodeku

Detail seriálu

Získanie informácií o seriáli s kompletným zoznamom sezón a epizód, zoskupených podľa čísla sezóny.

ID seriálu (UUID)

Polia poľa sezón

Číslo sezóny

Zobrazovaný názov sezóny

Počet epizód v sezóne

Dátum vysielania sezóny

Prehľad / popis sezóny

URL obrázka obalu sezóny

Objekt epizód

Mapa kľúčovaná reťazcom čísla sezóny. Každá hodnota je pole objektov epizód.

Polia objektu epizódy

ID epizódy

TMDB ID epizódy

Číslo epizódy v sezóne

Názov epizódy

Dátum pridania (ISO 8601)

Číslo sezóny

Objekt info epizódy (rovnaká štruktúra ako VOD info)

URL odkazy na stream

Metadáta video/audio kodeku

Poznámky

Expirácia tokenu závisí od roly používateľa: admin = 365 dní, ostatní = 30 dní|Zakázané účty sa nemôžu autentifikovať (vráti 403)|Každé úspešné prihlásenie aktualizuje časovú značku last_login používateľa|Tokeny sú šifrované a obsahujú user_id, username, role a expiráciu

Úspešná odpoveď (200)

Auth token získaný z /auth endpointu