B2C · Xtream · Reseller





Livelli archiviazione
Sistema di archiviazione a tre livelli per 500+ client concorrenti. Configura in Configura > Archiviazione > Livelli archiviazione. Ogni livello ha lifecycle, calcolo capacità e comportamento di fallback indipendenti.
Encoder
Buffer di scrittura
2h finestra calda (NVMe o tmpfs)
→ mirror (continuo)
HDD RAID 5
50 TB, 14 giorni retention
→ prefetch su richiesta
Cache riproduzione
1 TB cache warm, 500+ client
Client
I segmenti più vecchi di mirror_min_age_minutes vengono COPIATI su RAID in modo continuo. Il write_buffer mantiene una finestra calda rotante di 2h quindi il rewind-to-recent playback rimane su storage veloce. Solo dopo evict_age_minutes (e solo quando verificato-mirrorato) i segmenti vengono eliminati da write_buffer. RAID ha sempre la copia a lungo termine — nessun trasferimento burst orario.
Livello
Scopo
Impostazioni
Buffer di scrittura
Riceve segments 24/7, mantiene 2h hot window per playback recente-rewind veloce, protegge RAID da random IO. Il device può essere una partizione NVMe fisica (produzione) o tmpfs (dev/test box senza NVMe fisico — vedi sezione tmpfs sotto).
device_path (block device o 'tmpfs'), tmpfs_size_pct (10-50% MemAvailable quando tmpfs), mirror_min_age_minutes, evict_age_minutes, flush_threshold_percent (force flush trigger)
Archiviazione HDD RAID
Storage a lungo termine per retention completa (predefinito 14 giorni). Riceve mirror trickle continuo da write_buffer — scrittura sequenziale, nessun burst orario. Sopravvive al reboot. RAID sopravvive a singolo disk failure.
retention_days, raid_device, nginx_location, min_free_percent
Playback Cache (opzionale)
Cache lato lettura per file popolari più vecchi di 2h (es. EPG catch-up). Popolata da archive on demand dopo soglia popolarità (3 hits / 5 min). Il device può essere NVMe o tmpfs.
prefetch_hours, max_sessions, eviction_policy (session/lru/fifo)
live writes × 2h = write_buffer hot window. Esempio: 50 stream × 8 Mbps × 2h ≈ 36 GB
Stream.dvr_file_path/2 probes write_buffer → playback_cache → archive in ordine. Un segmento nella finestra calda 2h viene servito da write_buffer a velocità native anche se esiste anche su RAID. Nginx X-Accel-Redirect serve i file direttamente senza passare per Phoenix.
Ogni tier può usare un disk virtuale tmpfs backed da RAM invece di un block device fisico. Utile per dev box senza NVMe spare, o per ambienti test ephemeral. Il dropdown device della carta Storage Tier contiene un'opzione 'tmpfs (disk virtuale da RAM)' che sostituisce il selector del device path con uno slider percentuale.
L'allocazione viene specificata come percentuale di MemAvailable (da /proc/meminfo) — step 10, valori validi 10/20/30/40/50. Hard floor 10% (validation rejects below). Hard ceiling 50%. Predefinito 30%. Su un host 100 GB MemAvailable: 10% = 10 GB, 30% = 30 GB, 50% = 50 GB. La size viene ricalcolata e remountata live quando lo slider viene mosso e salvato.
Se il target calcolato supererebbe il 60% di MemAvailable corrente, il mount viene rifiutato e il tier rimane offline (Stream.archive_path cade al prossimo tier healthy). Previene un'impostazione aggressiva dal uccidere il BEAM via OOM. Il guard viene eseguito sia ad ogni boot che ad ogni Salvataggio nell'UI.
tmpfs vive in RAM — qualsiasi buffer in-flight content viene PERSO quando l'host si reboota. L'entry fstab scritta al provision time si rimonta il tmpfs vuoto automaticamente al prossimo boot, ma i vecchi segmenti non ritornano. Il mirror all'archive continua normalmente per tutto ciò che era già mirrorato prima del reboot — solo l'ultima finestra non-mirrorata (tipicamente < mirror_min_age_minutes) viene persa. Per produzione, usa un device NVMe fisico; tmpfs è inteso come sostituto dev/test.
Usa tmpfs per write_buffer quando: (a) dev/test box non ha NVMe spare ma vuoi comunque la pipeline DVR completa in esecuzione per integration testing, (b) l'operatore vuole validare il mirror + archive behaviour senza comprare NVMe upfront, (c) test ephemeral dove loss-on-reboot è accettabile. NON usare tmpfs in produzione — la RAM è volatile e di ordini di grandezza più costosa di NVMe per GB di retention.
Quando il write tier è tmpfs, StorageTierFlush usa default più tight — mirror_min_age 2 min, evict_age 15 min (vs 5 min / 120 min per NVMe fisico). La RAM è più costosa del disk quindi la rolling hot window è più piccola. Sovrascrivi via MIRROR_MIN_AGE_MINUTES / EVICT_AGE_MINUTES env vars se necessario.
I livelli vengono configurati una volta tramite Configura > Archiviazione > Livelli archiviazione e provisions automaticamente — nessuna modifica manuale mkfs/mount/fstab sull'host. StorageTier.ensure_all_provisioned/0 esegue ad ogni boot da SystemInitializer ed è idempotente: i livelli già montati vengono saltati, i device mancanti sono no-op, i tier tmpfs si rimontano puliti dopo il reboot.
Al primo avvio (nessun write tier in DB), il sistema crea automaticamente un write tier backed da tmpfs con allocazione 30% MemAvailable, punto di montaggio /mnt/nvme_write. Questo fornisce una pipeline DVR funzionante out-of-the-box su qualsiasi host con RAM sufficiente. L'operatore può successivamente cambiare device su NVMe fisico tramite UI senza perdere altre impostazioni tier.
Stream.archive_path/1 restituisce il primo livello 'healthy' — write_buffer se montato+scrivibile+free_pct sopra il floor di sicurezza, altrimenti fallback su archive (modalità degradata). Floor sicurezza 20% per tmpfs (RAM-strict), 2% per block device. L'endpoint tier_health espone mounted/writable/free_pct per monitoraggio.
Modificare tmpfs_size_pct nell'UI attiva umount + remount con la nuova dimensione al Salvataggio. Le scritture DVR attive vengono brevemente pausate (transizione mount < 1 s). Raccomandazione: modifica tmpfs size solo quando il rate di scrittura DVR è basso, e considera riavviare gli stream dopo per assicurare che pick up il nuovo mount pulito.
URL base — OSTV Player
Campi package
API Packages
Politica password
API Reseller
Impostazioni
Campi utente
Gestione utenti
URL base — OSTV Player
L'applicazione OSTV Player consente agli utenti di modificare l'URL base del server (indirizzo API). Questa funzione è disponibile solo per gli utenti con provider impostato su root.
Motivo: la modifica dell'URL base è destinata solo agli amministratori/utenti root per poter passare da un server all'altro (es. produzione vs test). Gli utenti normali hanno un URL base fisso e non possono modificarlo.
Campi utente
API Pacchetti
Restituisce un elenco di tutti i pacchetti attivi con prezzi e periodi di fatturazione.
Elenco degli utenti di gestione (rivenditori / provider).
Restituisce il saldo credito per un utente di gestione specifico.
Campi pacchetto
API Rivenditore
API per rivenditori/provider. Autorizzazione: Authorization: Bearer mtk_... (token da Gestione Utenti). Il rivenditore vede solo i propri clienti (owner_id).
Criteri per le password
La password è obbligatoria alla creazione di un abbonato. Regole:
Minimo 8 caratteri
Almeno 1 lettera maiuscola (A-Z)
Almeno 1 carattere speciale (!@#$%^&* ecc.)
Si applica a UI e API. In caso di aggiornamento, la password è opzionale, ma se fornita deve rispettare le regole.
Impostazioni
Provisioning automatico tier e sicurezza
Rilevamento automatico capacità + filesystem: quando si seleziona un NVMe libero dal menu a discesa, la capacità (GB) viene letta da lsblk -bn -o SIZE e il FS corrente da blkid (con fallback su disco intero). Il modulo mostra i valori in sola lettura — nessuna voce manuale, nessun errore.
Meccanismo di flush tier — Mirror continuo
Il GenServer StorageTierFlush viene eseguito ogni 60s. Invece di aspettare che una directory-ora "invecchi" e spostarla come burst da 5GB, trasferisce i segmenti su RAID continuamente mantenendo una finestra calda di 2h su NVMe per la riproduzione rapida "rewind recente". Le due fasi sono disaccoppiate — copia e cancellazione sono operazioni separate e verificate.
Perché il mirror continuo è meglio di "aspetta 60min, sposta in batch": (1) Il carico RAID è uniforme — nessun burst da 5GB ai confini delle ore, solo flusso di segmenti da 7MB; (2) La maggior parte dei dati caldi è già su RAID — il disaster recovery perde solo gli ultimi minuti; (3) L'eliminazione è verificata per file — un errore parziale del mirror viene rilevato prima che i dati NVMe vengano persi.
Sicurezza dei segmenti in corso: il mirror seleziona solo i file più vecchi di MIRROR_MIN_AGE_MINUTES tramite find -mmin +5. Un file di segmento ancora in fase di scrittura da FFmpeg non apparirà nell'elenco — nessuna possibilità di trasferimento parziale.
Tuning per deployment (.env)
500–1000
Regola di dimensionamento:
Calendario anteprima DVR
La scheda Anteprima DVR mostra un calendario renderizzato lato server che evidenzia solo i giorni per i quali esistono registrazioni su disco. La scansione viene eseguita su ogni tier (write_buffer + read_cache + archive + legacy) così un segmento appena spostato da NVMe a RAID rimane visibile senza ritardi.
I giorni con registrazioni sono cliccabili (blu) — cliccare precompila l'input data/ora con quel giorno alle 00:00; l'utente seleziona poi l'ora. I giorni senza registrazioni sono attenuati e inattivi.
Implementato in Stream.available_dvr_days/1 tramite find -mindepth 4 -maxdepth 4 -type d su ogni mount tier; deduplicato tra i tier (un giorno viene mostrato una sola volta anche se ha segmenti in più tier durante una finestra di flush).
Panoramica
L'API B2C fornisce funzionalità complete di gestione contenuti, streaming e autenticazione. Tutte le chiamate API richiedono un token di autenticazione valido, ottenuto tramite l'endpoint di autenticazione.
Autentica un utente e ottieni un auth_token per le chiamate API successive.
Metodo
Endpoint
Corpo richiesta
Parametro
Tipo
Obbligatorio
Descrizione
Si
Nome di accesso dell utente
Password dell'utente
Esempio di richiesta
Campi risposta
Risposta di successo
Token di autenticazione crittografato per le chiamate API successive
Data/ora di scadenza del token in formato ISO 8601
Esempio di risposta di successo
Risposta di errore
Messaggio di descrizione dell'errore
Codice di stato HTTP
Esempio di risposta di errore
Recupera le informazioni sull'utente autenticato utilizzando il token di autenticazione.
Campi di risposta
Nome utente dell utente autenticato
Messaggio del server (vuoto se nessuno)
Stato autenticazione (1 = autenticato)
Stato account: Attivo, Bannato, Disabilitato, Prova
Data di scadenza account (null se illimitato)
Numero di connessioni attive correnti
Data di creazione account in formato ISO 8601
Numero massimo di connessioni simultanee consentite
Elenco dei formati di stream consentiti
Nome provider del proprietario/reseller dell utente (null se nessuno)
URL immagine logo provider (null se nessuno)
URL immagine logo provider collapse 208x208 (null se nessuno)
Orario server corrente in formato ISO 8601
Esempio richiesta
Recupera categorie filtrate per tipo. Tipi disponibili: live (stream), vod (film), series (serie).
Tipo di categoria: live, vod o series
ID categoria come stringa
Nome visualizzato della categoria
ID categoria padre (0 se radice)
Hash MD5 del contenuto per invalidazione della cache
Esempio di richiesta
Recupera le informazioni dettagliate per un elemento VOD specifico, inclusi metadata e link di streaming.
ID stream VOD (UUID)
URL immagine di copertina
Identificatore TMDB
URL immagine di sfondo
Genere
Trama/descrizione
Cast
Valutazione (0-10)
Nome del regista
Data di uscita
Durata in secondi
Durata come stringa formattata
Array di ID categorie
1 se contenuto per adulti, 0 altrimenti
ID stream VOD
Titolo VOD
Data di aggiunta (ISO 8601)
URL link stream
Metadata codec video/audio
Dettagli serie TV
ID serie
Numero stagione
Nome visualizzazione stagione
Numero di episodi nella stagione
Data di trasmissione della stagione
Panoramica/descrizione della stagione
URL immagine di copertina della stagione
Mappa con chiave come numero di stagione. Ogni valore è un array di oggetti episodio.
Campi dell'Oggetto Episodio
ID episodio
ID episodio TMDB
Numero episodio
Episodio aggiunto alla serie
Numero di stagione
Informazioni episodio
Link episodio
Metadata episodio
La scadenza del token dipende dal ruolo dell'utente: admin = 365 giorni, altro = 30 giorni|Gli account disabilitati non possono autenticarsi (restaura 403)|Ogni accesso aggiorna il timestamp last_login dell'utente|I token sono crittografati e contengono user_id, username, ruolo e scadenza
Risposta di successo (200)
Token di autenticazione ottenuto dall endpoint /auth