Backend Go: - Remplacement complet des anciennes migrations par la base V1 alignée sur ORIGIN. - Durcissement global du parsing JSON (BindAndValidateJSON + RespondWithAppError). - Sécurisation de config.go, CORS, statuts de santé et monitoring. - Implémentation des transactions P0 (RBAC, duplication de playlists, social toggles). - Ajout d’un job worker structuré (emails, analytics, thumbnails) + tests associés. - Nouvelle doc backend : AUDIT_CONFIG, BACKEND_CONFIG, AUTH_PASSWORD_RESET, JOB_WORKER_*. Chat server (Rust): - Refonte du pipeline JWT + sécurité, audit et rate limiting avancé. - Implémentation complète du cycle de message (read receipts, delivered, edit/delete, typing). - Nettoyage des panics, gestion d’erreurs robuste, logs structurés. - Migrations chat alignées sur le schéma UUID et nouvelles features. Stream server (Rust): - Refonte du moteur de streaming (encoding pipeline + HLS) et des modules core. - Transactions P0 pour les jobs et segments, garanties d’atomicité. - Documentation détaillée de la pipeline (AUDIT_STREAM_*, DESIGN_STREAM_PIPELINE, TRANSACTIONS_P0_IMPLEMENTATION). Documentation & audits: - TRIAGE.md et AUDIT_STABILITY.md à jour avec l’état réel des 3 services. - Cartographie complète des migrations et des transactions (DB_MIGRATIONS_*, DB_TRANSACTION_PLAN, AUDIT_DB_TRANSACTIONS, TRANSACTION_TESTS_PHASE3). - Scripts de reset et de cleanup pour la lab DB et la V1. Ce commit fige l’ensemble du travail de stabilisation P0 (UUID, backend, chat et stream) avant les phases suivantes (Coherence Guardian, WS hardening, etc.).
7.8 KiB
🎵 Pipeline de streaming audio - Documentation
Date: 2025-01-27
Version: 0.2.0
Vue d'ensemble
Le pipeline de transcodage audio de Veza permet de convertir des fichiers audio en format HLS (HTTP Live Streaming) pour le streaming web. Il utilise FFmpeg pour l'encodage et un système de workers asynchrones pour le traitement parallèle.
Architecture
Composants principaux
-
TranscodingEngine: Orchestrateur principal
- Gère la file d'attente des jobs
- Lance et supervise les workers
- Stocke l'état des jobs via JobManager
-
JobManager: Stockage en mémoire des jobs
- Enregistre les jobs soumis
- Met à jour l'état des jobs
- Permet de récupérer l'état d'un job
-
PriorityQueue: File d'attente prioritaire
- 3 niveaux: Urgent, Normal, Background
- Capacité: 1000 jobs par défaut
- Backpressure si queue pleine
-
TranscodingWorker: Worker de traitement
- Traite un job à la fois
- Exécute FFmpeg avec timeout
- Gère les erreurs et retry
-
FfmpegCommandBuilder: Construction de commandes FFmpeg
- Support AAC, MP3, Opus, FLAC
- Génération HLS avec segments
- Validation des paramètres
Workflow
1. Soumission d'un job
Client → POST /v1/stream/transcode
↓
Routes::transcode_handler
↓
TranscodingEngine::submit()
↓
JobManager::enqueue() → PriorityQueue::submit()
↓
Worker récupère le job et traite
2. Traitement d'un job
Worker::process()
↓
Créer répertoire de sortie
↓
FfmpegCommandBuilder::build()
↓
Command::spawn() → FFmpeg process
↓
Timeout (5 min) ou completion
↓
Vérifier manifest HLS généré
↓
JobManager::update_job()
3. Récupération de l'état
Client → GET /v1/stream/job/{id}
↓
Routes::get_job_status()
↓
JobManager::get_status()
↓
Retour JSON avec état
4. Streaming HLS
Client → GET /v1/stream/hls/{job_id}/index.m3u8
↓
Routes::serve_hls_manifest()
↓
Lire index.m3u8 depuis output_dir
↓
Retour avec Content-Type: application/vnd.apple.mpegurl
Structure des fichiers de sortie
{output_dir}/
transcode_{uuid}/
index.m3u8 # Master playlist HLS
segment_00001.ts # Segment 1
segment_00002.ts # Segment 2
segment_00003.ts # Segment 3
...
Format du manifest HLS
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:6
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:6.0,
segment_00001.ts
#EXTINF:6.0,
segment_00002.ts
#EXTINF:6.0,
segment_00003.ts
#EXT-X-ENDLIST
API REST
POST /v1/stream/transcode
Soumet un fichier audio pour transcodage.
Request (multipart/form-data):
file: Fichier audio (WAV, MP3, FLAC, etc.)codec: Codec cible (aac, mp3, opus, flac) - optionnelbitrate: Bitrate en bps - optionnelquality_profile: Profil (hi_res, high, medium, low) - optionnelpriority: Priorité (urgent, normal, background) - optionnel
Response:
{
"job_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "queued",
"message": "Job submitted successfully"
}
GET /v1/stream/job/{id}
Récupère l'état d'un job.
Response:
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"track_id": "my_track",
"status": "processing",
"progress": 45.5,
"created_at": "SystemTime { tv_sec: 1737979200, tv_nsec: 0 }",
"started_at": "Some(SystemTime { tv_sec: 1737979205, tv_nsec: 0 })",
"completed_at": null,
"error": null
}
Statuts possibles:
Pending: Job en attenteProcessing: Job en cours de traitementCompleted: Job terminé avec succèsFailed(String): Job échoué avec message d'erreurCancelled: Job annulé
GET /v1/stream/hls/{job_id}/index.m3u8
Sert le manifest HLS pour un job terminé.
Response: Contenu du fichier index.m3u8 avec Content-Type: application/vnd.apple.mpegurl
GET /v1/stream/hls/{job_id}/{segment}
Sert un segment HLS (.ts).
Response: Contenu binaire du segment avec Content-Type: video/mp2t
Profils de qualité
hi_res
- Bitrate: 320 kbps
- Sample rate: 48 kHz
- Channels: 2 (stéréo)
- Codec: AAC
- Segment time: 6 secondes
high
- Bitrate: 192 kbps
- Sample rate: 44.1 kHz
- Channels: 2 (stéréo)
- Codec: AAC
- Segment time: 6 secondes
medium (défaut)
- Bitrate: 128 kbps
- Sample rate: 44.1 kHz
- Channels: 2 (stéréo)
- Codec: AAC
- Segment time: 6 secondes
low
- Bitrate: 64 kbps
- Sample rate: 22.05 kHz
- Channels: 1 (mono)
- Codec: AAC
- Segment time: 6 secondes
Gestion des erreurs
Types d'erreurs
- InputNotFound: Fichier d'entrée introuvable
- FfmpegError: Erreur d'exécution FFmpeg
- Timeout: Transcodage dépassant 5 minutes
- OutputDirError: Échec création répertoire de sortie
- ManifestMissing: Manifest HLS non généré
Retry logic
- Max retries: 3
- Conditions: Erreurs temporaires uniquement (timeout, IO)
- Pas de retry: Fichier corrompu, erreur permanente
Timeout
- Durée: 5 minutes par défaut
- Action: Processus FFmpeg tué automatiquement
- État: Job marqué comme
Failed("Transcoding timed out")
Configuration
Variables d'environnement
COMPRESSION_OUTPUT_DIR: Répertoire de sortie (défaut:/tmp)FFMPEG_PATH: Chemin vers FFmpeg (optionnel, cherche dans PATH)
Workers
- Nombre:
num_cpus()par défaut - Capacité queue: 1000 jobs
- Timeout: 5 minutes par job
Limitations P0
- ❌ Pas de multi-bitrate adaptatif (ABR)
- ❌ Pas de DRM
- ❌ Pas de persistance en base de données (mémoire uniquement)
- ❌ Pas de cleanup automatique des anciens jobs
- ❌ Pas de métriques Prometheus détaillées
- ❌ Pas de validation FFmpeg installé au démarrage
Exemples d'utilisation
cURL
# Soumettre un job
curl -X POST http://localhost:8082/v1/stream/transcode \
-F "file=@audio.wav" \
-F "quality_profile=high"
# Récupérer l'état
curl http://localhost:8082/v1/stream/job/{job_id}
# Servir le manifest HLS
curl http://localhost:8082/v1/stream/hls/{job_id}/index.m3u8
# Servir un segment
curl http://localhost:8082/v1/stream/hls/{job_id}/segment_00001.ts
JavaScript (fetch)
// Soumettre un job
const formData = new FormData();
formData.append('file', audioFile);
formData.append('quality_profile', 'high');
const response = await fetch('http://localhost:8082/v1/stream/transcode', {
method: 'POST',
body: formData
});
const { job_id } = await response.json();
// Poller l'état
const statusResponse = await fetch(`http://localhost:8082/v1/stream/job/${job_id}`);
const status = await statusResponse.json();
if (status.status === 'Completed') {
// Charger le manifest HLS
const manifestUrl = `http://localhost:8082/v1/stream/hls/${job_id}/index.m3u8`;
// Utiliser un player HLS (hls.js, video.js, etc.)
}
Performance
Coûts CPU/RAM
- CPU: ~1 core par worker actif
- RAM: ~50-100 MB par job en cours
- Disque: ~10-20 MB par minute d'audio (selon bitrate)
Recommandations
- Workers: 1-2x nombre de CPUs
- Queue capacity: 1000 jobs (ajustable selon charge)
- Timeout: 5 minutes (ajustable selon longueur fichiers)
Troubleshooting
Job reste en "Pending"
- Vérifier que les workers sont démarrés (
TranscodingEngine::start()) - Vérifier les logs pour erreurs de workers
- Vérifier que FFmpeg est installé et accessible
Job échoue avec "ManifestMissing"
- Vérifier que le répertoire de sortie est accessible en écriture
- Vérifier les logs FFmpeg pour erreurs d'encodage
- Vérifier l'espace disque disponible
Timeout fréquents
- Augmenter le timeout dans
worker.rs(constJOB_TIMEOUT) - Vérifier la charge CPU
- Vérifier la taille des fichiers d'entrée
Prochaine étape: Voir FFMPEG_COMMANDS.md pour les détails techniques des commandes FFmpeg.