veza/veza-stream-server/docs/STREAM_PIPELINE.md
okinrev b7955a680c P0: stabilisation backend/chat/stream + nouvelle base migrations v1
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.).
2025-12-06 11:14:38 +01:00

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

  1. TranscodingEngine: Orchestrateur principal

    • Gère la file d'attente des jobs
    • Lance et supervise les workers
    • Stocke l'état des jobs via JobManager
  2. 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
  3. PriorityQueue: File d'attente prioritaire

    • 3 niveaux: Urgent, Normal, Background
    • Capacité: 1000 jobs par défaut
    • Backpressure si queue pleine
  4. TranscodingWorker: Worker de traitement

    • Traite un job à la fois
    • Exécute FFmpeg avec timeout
    • Gère les erreurs et retry
  5. 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) - optionnel
  • bitrate: Bitrate en bps - optionnel
  • quality_profile: Profil (hi_res, high, medium, low) - optionnel
  • priority: 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 attente
  • Processing: Job en cours de traitement
  • Completed: Job terminé avec succès
  • Failed(String): Job échoué avec message d'erreur
  • Cancelled: 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

  1. InputNotFound: Fichier d'entrée introuvable
  2. FfmpegError: Erreur d'exécution FFmpeg
  3. Timeout: Transcodage dépassant 5 minutes
  4. OutputDirError: Échec création répertoire de sortie
  5. 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 (const JOB_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.