198 lines
9.8 KiB
Gherkin
198 lines
9.8 KiB
Gherkin
# language: fr
|
|
Fonctionnalité: Architecture technique radio live
|
|
En tant que système
|
|
Je veux gérer efficacement les flux audio en temps réel
|
|
Afin d'assurer une diffusion stable et scalable des lives
|
|
|
|
Contexte:
|
|
Étant donné que l'infrastructure RoadWave est opérationnelle
|
|
Et que les serveurs Go avec Pion WebRTC sont actifs
|
|
|
|
Scénario: Ingestion WebRTC du flux créateur
|
|
Étant donné qu'un créateur démarre un live depuis son application mobile
|
|
Quand le flux audio WebRTC (Opus 48 kbps) arrive sur le serveur
|
|
Alors le serveur Go avec Pion WebRTC accepte la connexion
|
|
Et le flux est traité en temps réel
|
|
|
|
Scénario: Conversion temps réel Opus vers segments HLS
|
|
Étant donné qu'un flux WebRTC Opus est reçu par le serveur
|
|
Quand le serveur traite le flux
|
|
Alors FFmpeg convertit en segments HLS (.ts)
|
|
Et un fichier manifest .m3u8 est généré et mis à jour régulièrement
|
|
Et les segments ont une durée de 2 secondes chacun
|
|
|
|
Scénario: Distribution via NGINX Cache
|
|
Étant donné que les segments HLS sont générés
|
|
Quand un auditeur demande à rejoindre le live
|
|
Alors le manifest .m3u8 est servi via NGINX Cache (OVH)
|
|
Et les segments .ts sont cachés sur le cache NGINX
|
|
Et la distribution est globale avec latence minimale
|
|
|
|
Scénario: Lecture HLS native sur mobile iOS
|
|
Étant donné qu'un auditeur iOS rejoint un live
|
|
Quand l'application charge le flux HLS
|
|
Alors le player natif AVPlayer gère la lecture
|
|
Et le buffer de 15 secondes est appliqué automatiquement
|
|
Et la qualité s'adapte selon la connexion
|
|
|
|
Scénario: Lecture HLS native sur mobile Android
|
|
Étant donné qu'un auditeur Android rejoint un live
|
|
Quand l'application charge le flux HLS
|
|
Alors le player natif ExoPlayer gère la lecture
|
|
Et le buffer de 15 secondes est configuré
|
|
Et la qualité s'adapte selon la connexion
|
|
|
|
Scénario: Enregistrement parallèle du flux pour replay
|
|
Étant donné qu'un live est en cours
|
|
Alors un processus parallèle enregistre le flux Opus raw
|
|
Et l'enregistrement est stocké temporairement sur le serveur
|
|
Et l'enregistrement est indépendant de la diffusion HLS
|
|
|
|
Scénario: Traitement post-live asynchrone
|
|
Étant donné qu'un live vient de se terminer
|
|
Quand le processus post-live démarre
|
|
Alors un job asynchrone est créé dans la queue Redis
|
|
Et un worker Go récupère le job
|
|
Et le worker exécute FFmpeg pour les conversions
|
|
|
|
Scénario: Conversion Opus raw vers MP3 256 kbps
|
|
Étant donné qu'un worker traite un job post-live
|
|
Quand la conversion démarre
|
|
Alors FFmpeg convertit Opus raw en MP3 256 kbps
|
|
Et la normalisation audio à -14 LUFS est appliquée
|
|
Et les silences prolongés (>3 secondes) sont détectés et nettoyés
|
|
|
|
Scénario: Génération segments HLS pour le replay
|
|
Étant donné que le MP3 256 kbps est généré
|
|
Quand le worker crée les segments HLS
|
|
Alors des segments .ts de 10 secondes sont créés
|
|
Et un manifest .m3u8 est généré
|
|
Et les segments sont uploadés vers OVH Object Storage
|
|
|
|
Scénario: Publication automatique du replay
|
|
Étant donné que tous les segments HLS sont uploadés
|
|
Quand le worker finalise le job
|
|
Alors une entrée de contenu "replay" est créée en base PostgreSQL
|
|
Et le titre est "[REPLAY] [Titre live original]"
|
|
Et le type géographique est "Géo-neutre"
|
|
Et le replay est immédiatement disponible pour les auditeurs
|
|
|
|
Scénario: Suppression automatique fichier Opus raw après 7 jours
|
|
Étant donné qu'un replay est publié depuis 7 jours
|
|
Quand le job de nettoyage quotidien s'exécute
|
|
Alors le fichier Opus raw est supprimé du stockage
|
|
Et seul le MP3 256 kbps et les segments HLS sont conservés
|
|
Et l'espace de stockage est libéré
|
|
|
|
Scénario: Scalabilité horizontale des workers de conversion
|
|
Étant donné que 50 lives se terminent simultanément
|
|
Quand les jobs post-live sont créés
|
|
Alors les workers Go disponibles traitent les jobs en parallèle
|
|
Et si tous les workers sont occupés, les jobs attendent en queue Redis
|
|
Et de nouveaux workers peuvent être lancés automatiquement (Kubernetes)
|
|
|
|
Scénario: Limitation du nombre de lives simultanés (MVP)
|
|
Étant donné que l'infrastructure MVP est configurée pour 100 lives simultanés
|
|
Et que 100 lives sont actuellement en cours
|
|
Quand un nouveau créateur essaie de démarrer un live
|
|
Alors la demande est refusée avec le code erreur 503
|
|
Et le message "Capacité maximale atteinte. Veuillez réessayer dans quelques minutes" est retourné
|
|
Et la demande peut être mise en queue prioritaire si créateur Premium
|
|
|
|
Scénario: Monitoring des ressources serveur en temps réel
|
|
Étant donné que plusieurs lives sont en cours
|
|
Alors le système monitore en temps réel:
|
|
| métrique | seuil alerte |
|
|
| CPU utilisation | >80% |
|
|
| Mémoire utilisation | >85% |
|
|
| Bande passante upload | >80% capacité|
|
|
| Nombre connexions WebRTC | >90 |
|
|
| Latence moyenne CDN | >200ms |
|
|
Et si un seuil est dépassé, une alerte est envoyée à l'équipe technique
|
|
|
|
Scénario: Calcul du coût de bande passante CDN
|
|
Étant donné qu'un live a 100 auditeurs simultanés
|
|
Et que la qualité est 48 kbps Opus
|
|
Quand le live dure 1 heure
|
|
Alors la bande passante totale est d'environ 2.16 GB
|
|
Et le coût estimé infrastructure est d'environ 0.02€
|
|
Et ces métriques sont enregistrées pour facturation créateur si nécessaire
|
|
|
|
Scénario: Cache NGINX des segments HLS
|
|
Étant donné qu'un live est diffusé via NGINX Cache
|
|
Quand un segment .ts est généré
|
|
Alors le segment est uploadé vers OVH Object Storage origin
|
|
Et NGINX Cache met en cache le segment
|
|
Et les auditeurs suivants récupèrent le segment depuis le cache
|
|
Et la charge sur le serveur origin est réduite de ~90%
|
|
|
|
Scénario: Gestion de la latence WebRTC créateur
|
|
Étant donné qu'un créateur diffuse avec une connexion 4G
|
|
Quand la latence réseau augmente ponctuellement
|
|
Alors le buffer côté serveur absorbe les fluctuations
|
|
Et la qualité peut être réduite temporairement (48 kbps → 32 kbps)
|
|
Et un warning est affiché au créateur si la connexion est trop instable
|
|
|
|
Scénario: Détection automatique de la musique protégée (post-MVP)
|
|
Étant donné qu'un live contient de la musique en arrière-plan
|
|
Quand le système d'audio fingerprint analyse le flux
|
|
Alors une empreinte audio est calculée toutes les 30 secondes
|
|
Et l'empreinte est comparée à une base de données de contenus protégés
|
|
Et si une correspondance est trouvée, un warning est envoyé au créateur
|
|
Et si le créateur ne corrige pas sous 30 secondes, le live peut être arrêté
|
|
|
|
Scénario: Stockage des métadonnées de live en PostgreSQL
|
|
Étant donné qu'un créateur démarre un live
|
|
Alors les métadonnées suivantes sont enregistrées:
|
|
| champ | exemple valeur |
|
|
| live_id | uuid v4 |
|
|
| creator_id | uuid créateur |
|
|
| title | "Mon super live" |
|
|
| started_at | timestamp UTC |
|
|
| zone_geo | "Île-de-France" |
|
|
| tags | ["Actualité", "Tech"] |
|
|
| classification_age | "Tout public" |
|
|
Et ces données sont indexées pour recherche et analytics
|
|
|
|
Scénario: Cache Redis pour compteurs temps réel
|
|
Étant donné qu'un live est en cours
|
|
Alors Redis stocke les compteurs temps réel:
|
|
| clé Redis | valeur exemple |
|
|
| live:[live_id]:listeners | 247 |
|
|
| live:[live_id]:likes | 89 |
|
|
| live:[live_id]:reports | 0 |
|
|
Et ces compteurs sont mis à jour toutes les 2 secondes
|
|
Et les compteurs sont persistés en PostgreSQL toutes les 60 secondes
|
|
|
|
Scénario: Heartbeat auditeurs pour compteur précis
|
|
Étant donné qu'un auditeur écoute un live
|
|
Alors l'application envoie un heartbeat toutes les 10 secondes
|
|
Et le heartbeat met à jour le timestamp dans Redis
|
|
Et si aucun heartbeat n'est reçu pendant 30 secondes, l'auditeur est retiré du compteur
|
|
|
|
Scénario: Gestion des pannes serveur pendant un live
|
|
Étant donné qu'un live est en cours sur serveur A
|
|
Quand le serveur A tombe en panne
|
|
Alors Kubernetes redémarre automatiquement un pod
|
|
Mais le live en cours est perdu (pas de failover temps réel en MVP)
|
|
Et le créateur voit le message "Connexion perdue. Veuillez redémarrer le live"
|
|
Et les auditeurs voient "Le live est terminé suite à un problème technique"
|
|
|
|
Scénario: Backup automatique des enregistrements live
|
|
Étant donné qu'un live est enregistré en Opus raw
|
|
Quand l'enregistrement dépasse 10 minutes
|
|
Alors un backup incrémental est créé toutes les 10 minutes
|
|
Et le backup est stocké sur un stockage secondaire (S3-compatible)
|
|
Et en cas de crash serveur, le live peut être récupéré jusqu'au dernier backup
|
|
|
|
Scénario: Logs et audit trail des lives
|
|
Étant donné qu'un live démarre, se déroule et se termine
|
|
Alors tous les événements sont loggés:
|
|
| événement | détails enregistrés |
|
|
| Démarrage live | timestamp, creator_id, zone_geo |
|
|
| Auditeur rejoint | timestamp, user_id, position GPS |
|
|
| Auditeur quitte | timestamp, user_id, durée écoute |
|
|
| Signalement | timestamp, user_id, catégorie |
|
|
| Fin live | timestamp, durée totale, stats finales |
|
|
Et ces logs sont conservés 90 jours pour analytics et conformité RGPD
|