B2C · Xtream · Reseller





Warstwy magazynu archiwum
Trójwarstwowy system archiwum dla 500+ klientów współbieżnych. Konfiguruj w Konfiguracja > Magazyn > Warstwy magazynu. Każda warstwa ma niezależny cykl życia, obliczanie pojemności i zachowanie awaryjne.
Koder
Bufor zapisu
Okno 2h na żywo (NVMe lub tmpfs)
→ mirror (ciągły)
HDD RAID 5
50 TB, retencja 14 dni
→ prefetch na żądanie
Podręczna pamięć odtwarzania
1 TB warm cache, 500+ klientów
Klienci
Segmenty starsze niż mirror_min_age_minutes są KOPIOWANE do RAID w sposób ciągły. Write_buffer przechowuje toczące się okno 2h na żywo, aby przesunięcie do ostatniego odtwarzania pozostało na szybkim magazynie. Tylko po evict_age_minutes (i tylko po zweryfikowaniu zwierciadła) segmenty są usuwane z write_buffer. RAID zawsze ma kopię na długi ogon — żadne transfery skokami godzinowe.
Warstwa
Cel
Ustawienia
Bufor zapisu
Otrzymuje segmenty 24/7, trzyma 2h okno hot dla szybkiego odtwarzania wstecznego, chroni RAID przed losowym IO. Urządzenie może być partycją fizycznego NVMe (produkcja) lub tmpfs (dev/test box bez fizycznego NVMe — zobacz sekcję tmpfs poniżej).
device_path (urządzenie blokowe lub "tmpfs"), tmpfs_size_pct (10-50% MemAvailable gdy tmpfs), mirror_min_age_minutes, evict_age_minutes, flush_threshold_percent (wyzwalacz wymuszenia)
Archiwum HDD RAID
Magazyn długoterminowy do pełnego przechowywania (domyślnie 14 dni). Otrzymuje ciągły strumień kopii zapasowej z write_buffer — sekwencyjny zapis, bez skoków godzinowych. Przeżywa restart. RAID przetrwa pojedynczą awarię dysku.
retention_days, raid_device, nginx_location, min_free_percent
Pamięć podręczna odtwarzania (opcjonalnie)
Podręczna pamięć odczytu dla popularnych plików starszych niż 2h (np. dogranie EPG). Wypełniana z archive na żądanie po przekroczeniu progu popularności (3 trafienia / 5 min). Urządzenie może być NVMe lub tmpfs.
prefetch_hours, max_sessions, eviction_policy (session/lru/fifo)
live writes × 2h = rozmiar okna hot write_buffer. Przykład: 50 strumieni × 8 Mbps × 2h ≈ 36 GB. Dodaj ~30% zapasu na zaległości mirror trickle → ~50 GB write_buffer wystarczy dla 50 strumieni. RAID rozmiarowany na pełną retencję: 50 × 8 Mbps × 14 dni ≈ 6 TB.
Stream.dvr_file_path/2 sonduje write_buffer → playback_cache → archiwum w kolejności. Segment w oknie 2h na żywo jest serwowany z write_buffer z natywną prędkością, choć istnieje również w RAID. Nginx X-Accel-Redirect serwuje pliki bezpośrednio bez przechodzenia przez Phoenix.
Każda warstwa może używać wirtualnego dysku tmpfs wspieranego przez RAM zamiast fizycznego urządzenia blokowego. Przydatne dla pudełek deweloperskich bez zapasowego dysku NVMe lub dla efemerycznych środowisk testowych. Karty warstwy magazynu zawierają opcję urządzenia "tmpfs (wirtualny dysk z RAM)", która zastępuje selektor ścieżki urządzenia suwakiem procentowym.
Alokacja jest określona jako procent MemAvailable (z /proc/meminfo) — krok 10, prawidłowe wartości 10/20/30/40/50. Twardy minimalny 10% (walidacja odrzuca poniżej). Twarda górna granica 50%. Domyślnie 30%. Na hoście z 100 GB MemAvailable: 10% = 10 GB, 30% = 30 GB, 50% = 50 GB. Rozmiar jest przeliczany i remontowany na żywo przy przesunięciu suwaka i zapisaniu.
Jeśli obliczony cel przekroczy 60% obecnego MemAvailable, montaż jest odrzucany i warstwa pozostaje offline (Stream.archive_path spada do następnej zdrowej warstwy). Zapobiega agresywnemu ustawieniu zabijającemu BEAM przez OOM. Ochrona działa zarówno przy starcie, jak i przy każdym Zapisie w interfejsie.
tmpfs działa w pamięci RAM — wszelkie dane w buforze są TRACONE po ponownym uruchomieniu hosta. Wpis fstab zapisany podczas przygotowania ponownie montuje pustą przestrzeń tmpfs automatycznie przy następnym uruchomieniu, ale stare segmenty nie powracają. Lustrzane odbicie do archiwum kontynuuje działanie normalnie dla wszystkich danych, które zostały już skopiowane przed ponownym uruchomieniem — traciona jest tylko ostatnia nieprzesłana okna (zazwyczaj odpowiadająca wartości < mirror_min_age_minutes). W środowisku produkcyjnym należy użyć fizycznego dysku NVMe; tmpfs jest przeznaczony jako zamiennik dla środowisk deweloperskich/testowych.
Użyj tmpfs dla write_buffer, gdy: (a) maszyna dew/test nie ma wolnego dysku NVMe, ale chcesz uruchomić pełny potok DVR do testów integracyjnych, (b) operator chce zweryfikować zachowanie lustrzanego odbicia i archiwizacji bez kupowania NVMe na start, (c) testy tymczasowe, w których utrata danych przy ponownym uruchomieniu jest akceptowalna. NIE używaj tmpfs w środowisku produkcyjnym — pamięć RAM jest ulotna i rzędy wielkości droższa niż NVMe przy przeliczeniu na GB przechowywanych danych.
Gdy warstwa zapisu to tmpfs, StorageTierFlush używa ściślejszych ustawień domyślnych — mirror_min_age 2 min, evict_age 15 min (vs 5 min / 120 min dla fizycznego NVMe). RAM jest droższy niż dysk, więc toczące się okno gorące jest utrzymywane mniejsze. Przesłoń za pośrednictwem zmiennych środowiskowych MIRROR_MIN_AGE_MINUTES / EVICT_AGE_MINUTES, jeśli potrzeba.
Warstwy są konfigurowane raz przez Konfiguracja > Magazyn > Warstwy magazynu i automatycznie zaopatrywane — brak ręcznego edytowania mkfs/mount/fstab na hoście. StorageTier.ensure_all_provisioned/0 uruchamiane jest przy każdym rozruchu z SystemInitializer i jest idempotentne: już zamontowane warstwy są pomijane, brakujące urządzenia to no-ops, warstwy tmpfs montują się czysto po ponownym uruchomieniu.
Przy pierwszym uruchomieniu (brak warstwy zapisu w DB), system automatycznie tworzy warstwę zapisu opartą na tmpfs z alokacją 30% MemAvailable, punkt montowania /mnt/nvme_write. Daje to działający pipeline DVR 'out-of-the-box' na każdym hoście z wystarczającą ilością RAM. Operator może później przełączyć urządzenie na fizyczny NVMe przez UI bez utraty ustawień innych warstw.
Stream.archive_path/1 zwraca pierwszą 'zdrową' warstwę — write_buffer jeśli zamontowany+do zapisu+free_pct powyżej progu bezpieczeństwa, w przeciwnym razie fallback do archive (tryb degradowany). Próg bezpieczeństwa 20% dla tmpfs (RAM-strict), 2% dla urządzeń blokowych. punkt końcowy tier_health udostępnia per-warstwowe mounted/writable/free_pct do monitoringu.
Zmiana tmpfs_size_pct w interfejsie wyzwala umount + remount z nowym rozmiarem na Zapisie. Aktywne zapisy DVR są krótko wstrzymywane (przejście montażu < 1 s). Zalecenie: zmienić rozmiar tmpfs tylko wtedy, gdy szybkość zapisu DVR jest niska, i rozważ restart strumieni, aby upewnić się, że poprawnie odbierają nowe montaż.
Podstawowy URL — OSTV Player
Pola pakietu
Interfejs API pakietów
Polityka haseł
Interfejs API sprzedawcy
Ustawienia
Pola użytkownika
Zarządzanie użytkownikami
Bazowy URL — OSTV Player
Aplikacja OSTV Player umożliwia użytkownikom zmianę bazowego URL serwera (adresu API). Funkcja dostępna tylko dla użytkowników z ustawionym dostawcą na root.
Powód: zmiana bazowego URL jest przeznaczona tylko dla administratorów/użytkowników root, aby mogli przełączać się między serwerami (np. produkcja a testowanie). Zwykli użytkownicy mają stały bazowy URL i nie mogą go zmieniać.
Pola użytkownika
API pakietów
Zwraca listę wszystkich aktywnych pakietów z cenami i okresami rozliczeniowymi.
Lista użytkowników zarządzania (resellerów / dostawców).
Zwraca saldo kredytowe dla określonego użytkownika zarządzania.
Pola pakietu
API resellerów
API dla resellerów/dostawców. Autoryzacja: Authorization: Bearer mtk_... (token z Zarządzaj użytkownikami). Reseller widzi tylko swoich klientów (owner_id).
Polityka haseł
Hasło jest wymagane przy tworzeniu abonenta. Zasady:
Minimum 8 znaków
Co najmniej 1 duża litera (A-Z)
Co najmniej 1 znak specjalny (!@#$%^&* itp.)
Dotyczy interfejsu i API. Przy aktualizacji hasło jest opcjonalne, ale jeśli podane, musi spełniać zasady.
Ustawienia
Auto-przydzielanie warstwy i bezpieczeństwo
Pojemność + auto-wykrywanie systemu plików: po wybraniu wolnego NVMe z listy, pojemność (GB) jest odczytywana z lsblk -bn -o SIZE, a bieżący system plików z blkid (z rezerwą całego dysku). Formularz wyświetla wartości tylko do odczytu — bez ręcznego wprowadzania, bez błędów.
Mechanizm opróżniania warstwy — ciągłe lustro
StorageTierFlush GenServer działa co 60 sekund. Zamiast czekać na "zestarzeenie się" katalogu godzinowego i przenosić go jako 5 GB burst, segmenty są ciągle przesyłane do RAID, zachowując 2-godzinne okno hot na NVMe do szybkiego przewijania. Dwie fazy są rozdzielone — kopiowanie i usuwanie to osobne, weryfikowane operacje.
Dlaczego ciągłe lustro jest lepsze od "czekaj 60 min, przenoś wsadowo": (1) obciążenie RAID jest równomierne — brak 5 GB burstów na granicach godzin; (2) większość gorących danych jest już na RAID — odzysk po awarii traci tylko ostatnie kilka minut; (3) eksmisja jest weryfikowana per plik — częściowa awaria kopiowania jest wykrywana przed utratą danych NVMe.
Bezpieczeństwo segmentów w trakcie zapisu: lustro pobiera tylko pliki starsze niż MIRROR_MIN_AGE_MINUTES przez find -mmin +5. Plik segmentu wciąż dopisywany przez FFmpeg nie pojawi się na liście — nie ma ryzyka transferu z niepełnym zapisem.
Dostrajanie per wdrożenie (.env)
500–1000
Reguła rozmiarowania:
Kalendarz podglądu DVR
Zakładka podglądu DVR pokazuje renderowany po stronie serwera kalendarz z podświetlonymi tylko dniami, dla których nagrania istnieją na dysku. Skanowanie przebiega po każdej warstwie (write_buffer + read_cache + archive + legacy), więc segment właśnie przeniesiony z NVMe na RAID pozostaje widoczny bez opóźnienia.
Dni z nagraniami są klikalne (niebieskie) — kliknięcie wypełnia wstępnie pole datetime tym dniem o 00:00; użytkownik następnie wybiera godzinę. Dni bez nagrań są wyszarzone i nieaktywne.
Zaimplementowane w Stream.available_dvr_days/1 przez find -mindepth 4 -maxdepth 4 -type d na każdym punkcie montowania warstwy; deduplikowane między warstwami (dzień jest pokazany raz, nawet jeśli ma segmenty w wielu warstwach podczas okna opróżniania).
Przegląd
API B2C (Business-to-Consumer) zapewnia uwierzytelnianie i dostęp do strumieni dla aplikacji odtwarzaczy końcowych użytkowników. Użytkownicy uwierzytelniają się za pomocą nazwy użytkownika i hasła, otrzymując token uwierzytelniający z ograniczonym czasem ważności do kolejnych żądań.
Uwierzytelnij użytkownika i uzyskaj token uwierzytelniający do kolejnych wywołań API.
Metoda
Punkt końcowy
Treść żądania
Parametr
Typ
Wymagane
Opis
Tak
Nazwa logowania użytkownika
Hasło użytkownika
Przykładowe żądanie
Pola odpowiedzi
Sukces (200)
Zaszyfrowany token uwierzytelniania dla kolejnych wywołań API
Data/godzina wygaśnięcia tokenu w formacie ISO 8601
Przykładowa odpowiedź sukcesu
Odpowiedź błędu (403)
Komunikat z opisem błędu
Kod stanu HTTP
Przykładowa odpowiedź błędu
Pobierz informacje o uwierzytelnionym użytkowniku za pomocą tokena uwierzytelniania.
Pola odpowiedzi
Nazwa użytkownika uwierzytelnionego użytkownika
Wiadomość serwera (pusta, jeśli brak)
Status uwierzytelniania (1 = uwierzytelniony)
Status konta: aktywny, zbanowany, wyłączony, próba
Data wygaśnięcia konta (null, jeśli nieograniczone)
Liczba bieżących aktywnych połączeń
Data utworzenia konta w formacie ISO 8601
Maksymalna dozwolona liczba jednoczesnych połączeń
Lista dozwolonych formatów strumienia wyjściowego
Nazwa dostawcy właściciela/sprzedawcy użytkownika (null, jeśli brak)
URL obrazu logotypu dostawcy (null jeśli brak)
URL obrazu logo dostawcy 208x208 (null, jeśli brak)
Aktualny czas serwera w formacie ISO 8601
Przykładowe żądanie
Pobierz kategorie filtrowane według typu. Dostępne typy: live (strumienie), vod (filmy), series (seriale).
Typ kategorii: live, vod lub series
Identyfikator kategorii jako ciąg
Nazwa wyświetlania kategorii
Identyfikator kategorii nadrzędnej (0 jeśli root)
Skrót MD5 treści do unieważniania pamięci podręcznej
Przykładowe żądanie
Pobierz szczegółowe informacje dla określonego elementu VOD, w tym metadane i linki do strumieni.
ID strumienia VOD (UUID)
URL obrazu okładki
Identyfikator TMDB
URL obrazu tła
Ciąg gatunku
Fabuła / opis
Członkowie obsady
Wartość oceny (0-10)
Nazwa reżysera
Data premiery
Czas trwania w sekundach
Czas trwania jako sformatowany ciąg
Tablica identyfikatorów kategorii
1 jeśli treść dla dorosłych, 0 w innym razie
ID strumienia VOD
Tytuł VOD
Data dodania (ISO 8601)
Adresy URL linków strumienia
Metadane kodeka wideo/audi
Pobierz informacje o serialu z pełnymi listami sezonów i odcinków, pogrupowanymi według numeru sezonu.
ID serialu (UUID)
Numer sezonu
Nazwa wyświetlania sezonu
Liczba odcinków w sezonie
Data premiery sezonu
Przegląd/opis sezonu
URL obrazu okładki sezonu
Mapa z kluczem będącym ciągiem numeru sezonu. Każda wartość to tablica obiektów odcinków.
Pola obiektu odcinka
ID odcinka
ID odcinka TMDB
Numer odcinka w sezonie
Data dodania (ISO 8601)
Numer sezonu
Obiekt informacji o odcinku (ta sama struktura co informacje VOD)
Adresy URL linków strumienia
Metadane kodeków wideo/audi
Ważność tokena zależy od roli użytkownika: admin = 365 dni, inne = 30 dni|Wyłączone konta nie mogą się uwierzytelniać (zwraca 403)|Każde pomyślne zalogowanie aktualizuje znacznik czasu ostatniego logowania użytkownika|Tokeny są szyfrowane i zawierają user_id, nazwę_użytkownika, rolę i datę ważności
Sukces Odpowiedź (200)
Token uwierzytelniania uzyskany z punktu końcowego /auth