B2C · Xtream · Reseller





Niveaux de stockage d'archive
Système d'archive à trois niveaux pour 500+ clients simultanés. Configurez dans Config > Stockage > Niveaux de stockage. Chaque niveau a un cycle de vie, un calcul de capacité et un comportement de repli indépendants.
Encodeur
Tampon d'écriture
Fenêtre chaude de 2h (NVMe ou tmpfs)
→ copie miroir (continue)
HDD RAID 5
50 To, rétention de 14 jours
→ préchargement à la demande
Cache de lecture
1 To de cache chaud, 500+ clients
Clients
Les segments antérieurs à mirror_min_age_minutes sont COPIÉS en continu vers le RAID. Le tampon d'écriture maintient une fenêtre chaude roulante de 2h afin que la lecture en arrière vers les segments récents reste sur un stockage rapide. Les segments ne sont supprimés du tampon d'écriture qu'après evict_age_minutes (et uniquement lorsque la copie miroir est vérifiée). Le RAID conserve toujours la copie longue durée — aucun transfert par rafale horaire.
Niveau
Objectif
Paramètres
Tampon d'écriture
Reçoit des segments 24h/24, conserve une fenêtre chaude de 2h pour une lecture rapide en rembobinage récent, protège le RAID contre les E/S aléatoires. Le périphérique peut être une partition NVMe physique (production) ou un tmpfs (boîte dev/test sans NVMe physique — voir section tmpfs ci-dessous).
device_path (périphérique bloc ou 'tmpfs'), tmpfs_size_pct (10-50% MemAvailable pour tmpfs), mirror_min_age_minutes, evict_age_minutes, flush_threshold_percent (déclencheur de vidange forcée)
Archive HDD RAID
Stockage longue traîne pour rétention complète (par défaut 14 jours). Reçoit un flux continu du write_buffer — écriture séquentielle, pas de rafales horaires. Survit au redémarrage. RAID survive à une défaillance de disque unique.
retention_days, raid_device, nginx_location, min_free_percent
Cache de lecture (optionnel)
Cache côté lecture pour les fichiers populaires de plus de 2h (ex. rattrapage EPG). Rempli depuis l'archive à la demande après le seuil de popularité (3 hits / 5 min). Le périphérique peut être un NVMe ou un tmpfs.
prefetch_hours, max_sessions, eviction_policy (session/lru/fifo)
écritures live × 2h = taille de la fenêtre chaude du tampon d'écriture. Exemple : 50 flux × 8 Mbps × 2h ≈ 36 Go. Ajoutez ~30 % de marge pour le retard de la copie miroir → ~50 Go de tampon d'écriture suffisent pour 50 flux. RAID dimensionné pour la rétention complète : 50 × 8 Mbps × 14 jours ≈ 6 To.
Stream.dvr_file_path/2 sonde write_buffer → playback_cache → archive dans cet ordre. Un segment dans la fenêtre chaude de 2h est servi depuis write_buffer à des vitesses natives même s'il existe également sur le RAID. Nginx X-Accel-Redirect sert les fichiers directement sans passer par Phoenix.
Chaque niveau peut utiliser un disque virtuel tmpfs basé sur la RAM au lieu d'un périphérique bloc physique. Utile pour les boîtes de développement sans NVMe de rechange, ou pour les environnements de test éphémères. Le menu déroulant du périphérique de la carte Storage Tier contient une option 'tmpfs (disque virtuel depuis la RAM)' qui remplace le sélecteur de chemin de périphérique par un curseur de pourcentage.
L'allocation est spécifiée comme un pourcentage de MemAvailable (de /proc/meminfo) — pas de 10, valeurs valides 10/20/30/40/50. Plancher dur 10 % (la validation rejette en dessous). Plafond dur 50 %. Par défaut 30 %. Sur un hôte avec 100 Go de MemAvailable : 10 % = 10 Go, 30 % = 30 Go, 50 % = 50 Go. La taille est recalculée et remontée en direct lorsque le curseur est déplacé et enregistré.
Si la cible calculée dépasserait 60 % de MemAvailable actuel, le montage est refusé et le niveau reste hors ligne (Stream.archive_path bascule vers le prochain niveau sain). Empêche un paramètre agressif de tuer le BEAM via OOM. Le garde-fou s'exécute au démarrage et à chaque enregistrement dans l'interface.
tmpfs vit dans la RAM — tout contenu de tampon en cours est PERDU lors du redémarrage de l'hôte. L'entrée fstab écrite au moment du provisionnement remonte le tmpfs vide automatiquement au prochain démarrage, mais les anciens segments ne reviennent pas. Le miroir vers l'archive continue normalement pour tout ce qui a déjà été miroité avant le redémarrage — seule la dernière fenêtre non miroitée (généralement < mirror_min_age_minutes) est perdue. Pour la production, utiliser un périphérique NVMe physique ; tmpfs est destiné à être un substitut dev/test.
Utiliser tmpfs pour write_buffer lorsque : (a) la boîte dev/test n'a pas de NVMe de rechange mais vous voulez tout de même faire fonctionner le pipeline DVR complet pour les tests d'intégration, (b) l'opérateur souhaite valider le comportement du miroir + archive sans acheter de NVMe à l'avance, (c) tests éphémères où la perte au redémarrage est acceptable. NE PAS utiliser tmpfs en production — la RAM est volatile et coûte plusieurs ordres de grandeur plus cher que le NVMe par Go de rétention.
Lorsque le niveau d'écriture est un tmpfs, StorageTierFlush utilise des valeurs par défaut plus strictes — mirror_min_age 2 min, evict_age 15 min (contre 5 min / 120 min pour NVMe physique). La RAM est plus coûteuse que le disque, donc la fenêtre chaude roulante est maintenue plus petite. Remplacer via les variables d'environnement MIRROR_MIN_AGE_MINUTES / EVICT_AGE_MINUTES si nécessaire.
Les niveaux sont configurés une fois via Config > Storage > Storage Tiers et provisionnés automatiquement — aucune édition manuelle de mkfs/mount/fstab sur l'hôte. StorageTier.ensure_all_provisioned/0 s'exécute à chaque démarrage via SystemInitializer et est idempotent : les niveaux déjà montés sont ignorés, les périphériques manquants sont ignorés, les niveaux tmpfs sont remontés proprement après redémarrage.
Au premier démarrage (aucun niveau d'écriture dans la base de données), le système crée automatiquement un niveau d'écriture basé sur tmpfs avec une allocation de 30 % de MemAvailable, point de montage /mnt/nvme_write. Cela fournit un pipeline DVR fonctionnel dès la sortie de l'emballage sur n'importe quel hôte disposant de suffisamment de RAM. L'opérateur peut ensuite basculer le périphérique vers un NVMe physique via l'interface utilisateur sans perdre les autres paramètres de niveau.
Stream.archive_path/1 renvoie le premier 'sain' — write_buffer si monté, writable et free_pct supérieur au seuil de sécurité, sinon bascule vers archive (mode dégradé). Seuil de sécurité de 20 % pour tmpfs (RAM-stricte), 2 % pour les périphériques bloc. L'endpoint tier_health expose mounted/writable/free_pct par niveau pour la surveillance.
La modification de tmpfs_size_pct dans l'interface déclenche un umount + remount avec la nouvelle taille lors de l'enregistrement. Les écritures DVR actives sont brièvement mises en pause (transition de montage < 1 s). Recommandation : modifier la taille tmpfs uniquement lorsque le taux d'écriture DVR est faible, et envisager de redémarrer les flux ensuite pour s'assurer qu'ils utilisent proprement le nouveau montage.
URL de base — OSTV Player
Champs de package
API des packages
Politique de mot de passe
API revendeur
Paramètres
Champs utilisateur
Gestion des utilisateurs
URL de base — OSTV Player
L'application OSTV Player permet aux utilisateurs de modifier l'URL de base du serveur (adresse API). Cette fonctionnalité est disponible uniquement pour les administrateurs/utilisateurs root.
Raison : La modification de l'URL de base est destinée uniquement aux administrateurs/utilisateurs root pour leur permettre de basculer entre les serveurs (ex. production / test).
Champs utilisateur
API des packages
Retourne une liste de tous les packages actifs avec les prix et les périodes de facturation.
Liste des utilisateurs de gestion (revendeurs / fournisseurs).
Retourne le solde de crédit d'un utilisateur de gestion spécifique.
Champs du package
API revendeur
API pour revendeurs/fournisseurs. Autorisation : Authorization: Bearer mtk_... (token depuis Gérer les utilisateurs). Un revendeur ne voit que ses propres abonnés.
Politique de mot de passe
Le mot de passe est requis lors de la création d'un abonné. Règles :
Minimum 8 caractères
Au moins 1 lettre majuscule (A-Z)
Au moins 1 caractère spécial (!@#$%^&* etc.)
S'applique à l'UI et à l'API. Lors de la mise à jour, le mot de passe est optionnel, mais s'il est fourni il doit respecter les règles.
Paramètres
Provisionnement automatique des niveaux & sécurité
Capacité + détection automatique du système de fichiers : lorsqu'un NVMe libre est sélectionné dans la liste déroulante, la capacité (Go) est lue depuis lsblk.
Mécanisme de vidage des niveaux — Miroir continu
StorageTierFlush GenServer s'exécute toutes les 60s. Au lieu d'attendre qu'un répertoire heure « vieillisse » et de le déplacer en bloc de 5 Go, il copie continuellement les fichiers terminés.
Pourquoi le miroir continu surpasse « attendre 60 min, déplacer par lots » : (1) La charge RAID est répartie — pas de pics de 5 Go aux limites des heures, juste un flux continu.
Sécurité des segments en cours : le miroir ne sélectionne que les fichiers plus anciens que MIRROR_MIN_AGE_MINUTES via find -mmin +5. Un segment en cours d'écriture n'est jamais copié.
Réglages par déploiement (.env)
Gestion des bouquets IPTV
Règle de dimensionnement :
Calendrier d'aperçu DVR
L'onglet Aperçu DVR affiche un calendrier rendu côté serveur qui met en évidence uniquement les jours pour lesquels des enregistrements existent sur le disque.
Les jours avec enregistrements sont cliquables (bleus) — cliquer pré-remplit la saisie datetime avec ce jour à 00:00 ; l'utilisateur sélectionne ensuite l'heure.
Implémenté dans Stream.available_dvr_days/1 via find -mindepth 4 -maxdepth 4 -type d sur chaque point de montage du niveau ; dédupliqué sur tous les niveaux.
Vue d'ensemble
L'API B2C (Business-to-Consumer) fournit l'authentification et l'accès aux flux pour les applications lecteur des utilisateurs finaux. Les utilisateurs s'authentifient avec un nom d'utilisateur/mot de passe et reçoivent un token d'authentification limité dans le temps pour les requêtes suivantes.
Authentifier un utilisateur et obtenir un auth_token pour les appels API suivants.
Méthode
Point de terminaison
Corps de la requête
Paramètre
Genre
Requis
Description
Oui
Nom de connexion utilisateur
Mot de passe utilisateur
Exemple de requête
Champs de réponse
Réponse réussie (200)
Token d'authentification chiffré pour les appels API suivants
Date/heure d'expiration du token au format ISO 8601
Exemple de réponse réussie
Réponse d'erreur (403)
Message de description de l'erreur
Code de statut HTTP
Exemple de réponse d'erreur
Récupère les informations sur l'utilisateur authentifié en utilisant le token auth.
Champs de réponse
Nom d'utilisateur de l'utilisateur authentifié
Message du serveur (vide si aucun)
Statut d'authentification (1 = authentifié)
Statut du compte : Actif, Banni, Désactivé, Essai
Date d'expiration du compte (null si illimité)
Nombre de connexions actives actuelles
Date de création du compte au format ISO 8601
Nombre maximum de connexions simultanées autorisées
Liste des formats de flux de sortie autorisés
Nom du fournisseur du propriétaire/revendeur de l'utilisateur (null si aucun)
URL de l'image du logo du fournisseur (null si aucun)
URL de l'image du logo réduit du fournisseur 208x208 (null si aucun)
Heure actuelle du serveur au format ISO 8601
Exemple de requête
Récupère les catégories filtrées par type. Types disponibles : live (flux), vod (films), series.
Type de catégorie : live, vod ou series
ID de catégorie sous forme de chaîne
Nom d'affichage de la catégorie
ID de catégorie parente (0 si racine)
Hachage MD5 du contenu pour l'invalidation du cache
Exemple de requête
Récupère les informations détaillées d'un élément VOD spécifique, y compris les métadonnées et les liens de flux.
ID du flux VOD (UUID)
URL de l'image de couverture
Identifiant TMDB
URL de l'image de fond
Chaîne de genre
Intrigue / description
Membres du casting
Valeur de notation (0-10)
Nom du réalisateur
Date de sortie
Durée en secondes
Durée sous forme de chaîne formatée
Tableau d'ID de catégories
1 si contenu adulte, 0 sinon
ID du flux VOD
Titre VOD
Date d'ajout (ISO 8601)
URL des liens de flux
Métadonnées de codec vidéo/audio
Récupère les informations de la série avec la liste complète des saisons et épisodes, groupés par numéro de saison.
ID de la série (UUID)
Numéro de saison
Nom d'affichage de la saison
Nombre d'épisodes dans la saison
Date de diffusion de la saison
Aperçu / description de la saison
URL de l'image de couverture de la saison
Carte indexée par numéro de saison (chaîne). Chaque valeur est un tableau d'objets épisode.
Champs de l'objet épisode
ID de l'épisode
ID d'épisode TMDB
Numéro d'épisode dans la saison
Date d'ajout (ISO 8601)
Numéro de saison
Objet d'information de l'épisode (même structure que l'info VOD)
URL des liens de flux
Métadonnées de codec vidéo/audio
L'expiration du token dépend du rôle de l'utilisateur : admin = 365 jours, autre = 30 jours|Les comptes désactivés ne peuvent pas s'authentifier (retourne 403)|Chaque connexion réussie met à jour l'horodatage last_login de l'utilisateur|Les tokens sont chiffrés et contiennent user_id, username, role et expiration
Réponse réussie (200)
Token auth obtenu depuis le point de terminaison /auth