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.).
13 KiB
🔍 AUDIT COMPLET - Moteur d'Encodage Audio
Date: 2025-01-27
Service: veza-stream-server
Mission: P0 - Implémentation complète du moteur d'encodage audio
1. ÉTAT ACTUEL DU CODE
1.1. Structures Existantes ✅
src/core/encoder.rs
-
EncoderPool: Structure définie mais VIDE (ligne 253:// TODO: Implémentation réelle des encodeurs)- Pool d'encodeurs par codec (Opus, AAC, MP3, FLAC)
- Métriques d'utilisation (
EncoderMetrics) - Configuration (
EncoderPoolConfig) - PROBLÈME: Les pools sont initialisés mais vides, aucun encodeur réel n'est créé
-
EncoderPipeline: Structure pour pipeline d'encodage- Support multi-sortie (
Vec<EncoderOutput>) - Chaîne d'effets audio
- PROBLÈME:
start_processing()est un TODO (ligne 459)
- Support multi-sortie (
-
AudioCodec: Enum complet avec Opus, AAC, MP3, FLAC- Configuration détaillée par codec
- ✅ Bien défini
-
QualityProfile: Profils prédéfinis (Voice, Music Standard, High, Lossless)- ✅ Fonctionnel
src/transcoding/ffmpeg/command_builder.rs
FfmpegCommandBuilder: Builder pattern pour commandes FFmpeg- ✅ Support HLS basique (
-f hls,-hls_time,-hls_playlist_type vod) - ✅ Support codecs audio (AAC, MP3, Opus, FLAC)
- ✅ Gestion bitrate, sample_rate, channels
- MANQUE: Option
-threads 1pour isolation CPU - MANQUE: Option
-map 0:apour forcer audio-only - MANQUE: Pattern de nommage segments personnalisable
- ✅ Support HLS basique (
src/transcoding/ffmpeg/progress_parser.rs
FfmpegProgress: Parser pour stderr FFmpeg- ✅ Parse frame, fps, time, bitrate, speed
- ✅ Regex robuste
- ✅ Support audio-only (sans frame/fps)
src/transcoding/pipeline/
-
TranscodingJob: Structure de job existante- ✅ UUID, track_id, input_path, output_dir
- ✅ Status (Pending, Processing, Completed, Failed, Cancelled)
- ✅ Priority (Background, Normal, Urgent)
- ✅ Progress tracking
- PROBLÈME: Utilise
Stringpourtrack_idau lieu deUuid
-
TranscodingWorker: Worker basique- ✅ Exécute FFmpeg avec timeout (5 min)
- ✅ Gestion erreurs et retry
- ✅ Vérification manifest HLS généré
- MANQUE: Pas de parsing des segments produits
- MANQUE: Pas de capture stderr en streaming
- MANQUE: Pas de persistance en DB
-
job_manager.rsetqueue.rs: Gestion de queue- ✅ Structure présente
- ⚠️ À vérifier l'intégration avec le nouveau système
src/audio/pipeline.rs
AudioPipeline: Pipeline de traitement audio- ✅ Décodage → Traitement → Encodage
- ✅ Support effets audio
- ✅ Normalisation
- NOTE: Conçu pour streaming temps réel, pas pour batch encoding
src/routes/transcode.rs
- Routes API existantes :
- ✅
POST /v1/stream/transcode - ✅
GET /v1/stream/job/:id - ✅
GET /v1/stream/hls/:job_id/index.m3u8 - ✅
GET /v1/stream/hls/:job_id/:segment - PROBLÈME: Utilise
job_idau lieu detrack_id+quality
- ✅
1.2. Ce Qui Manque Totalement ❌
-
Pool d'encodeurs fonctionnel
- Aucun worker thread réel
- Aucune queue async_channel
- Aucun spawn de processus FFmpeg
-
Structure
EncodeJob- Pas de structure dédiée pour encodage (utilise
TranscodingJobqui est générique) - Pas de mapping qualité → codec/bitrate automatique
- Pas de structure dédiée pour encodage (utilise
-
Pipeline d'encodage complet
- Pas de vérification
track.source_pathen DB - Pas de création répertoire
/data/streams/<track_id>/<quality>/ - Pas de parsing des segments HLS produits
- Pas d'insertion en DB (
stream_segments)
- Pas de vérification
-
Migrations SQL
- Table
stream_jobsn'existe pas - Table
stream_segmentsn'existe pas - Pas d'index pour performance
- Table
-
API REST manquante
POST /admin/stream/encode/:track_id(lance encodage)GET /admin/stream/status/:track_id(statut multi-qualité)GET /stream/:track_id/:quality/index.m3u8(playlist HLS)GET /stream/:track_id/:quality/segment_*.ts(segments)
-
Monitoring FFmpeg
- Pas de capture stderr en streaming
- Pas de logs tracing pour avancement
- Pas de détection crashes FFmpeg
-
Parsing segments HLS
- Pas de parsing du manifest
.m3u8pour extraire segments - Pas de calcul durée par segment
- Pas de validation segments générés
- Pas de parsing du manifest
1.3. Incohérences / À Refactor ⚠️
-
Duplication structures
src/core/encoder.rs:EncoderPool,EncoderPipeline(abstrait, traits)src/transcoding/pipeline/:TranscodingJob,TranscodingWorker(concret, FFmpeg)- SOLUTION: Utiliser
TranscodingJobcomme base, créerEncodeJobwrapper si besoin
-
Conventions MIME / Format
AudioCodecdanscore/encoder.rs(enum avec variants)AudioCodecdanstranscoding/codecs/mod.rs(enum simple)- SOLUTION: Unifier vers
transcoding/codecs/mod.rs
-
Gestion CPU concurrency
EncoderPoolConfig.max_parallel_encodes = num_cpus::get() * 2(trop agressif)- Pas de limite réelle dans
TranscodingWorker - SOLUTION: Pool avec
min(nb_cpu / 2, 8)workers
-
Handling erreurs FFmpeg
TranscodingWorkercapture exit code mais pas stderr détaillé- Pas de parsing erreurs spécifiques (codec manquant, file not found, etc.)
- SOLUTION: Parser stderr pour erreurs courantes
-
Routes API incohérentes
- Routes existantes:
/v1/stream/hls/:job_id/... - Besoin:
/stream/:track_id/:quality/... - SOLUTION: Garder les deux (rétrocompatibilité) ou migrer progressivement
- Routes existantes:
2. DESIGN PROPOSÉ
2.1. Architecture
┌─────────────────────────────────────────────────────────┐
│ API REST Layer │
│ POST /admin/stream/encode/:track_id │
│ GET /admin/stream/status/:track_id │
│ GET /stream/:track_id/:quality/index.m3u8 │
│ GET /stream/:track_id/:quality/segment_*.ts │
└────────────────────┬────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Encoding Service Layer │
│ - Vérifie track.source_path en DB │
│ - Crée répertoire /data/streams/<track_id>/<quality>/ │
│ - Crée EncodeJob et l'envoie dans la queue │
└────────────────────┬────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Encoder Pool (Worker Threads) │
│ - Queue: async_channel::Receiver<EncodeJob> │
│ - Workers: Vec<EncoderWorker> (1 thread = 1 FFmpeg) │
│ - Nombre: min(nb_cpu / 2, 8) │
└────────────────────┬────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ FFmpeg Execution │
│ - Build command avec FfmpegCommandBuilder │
│ - Spawn processus FFmpeg │
│ - Capture stderr en streaming │
│ - Parse progression (FfmpegProgress) │
│ - Détecte crashes et erreurs │
└────────────────────┬────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Post-Processing │
│ - Parse manifest .m3u8 pour extraire segments │
│ - Calcule durée par segment │
│ - Insère segments en DB (stream_segments) │
│ - Met à jour stream_jobs.status = 'done' │
└─────────────────────────────────────────────────────────┘
2.2. Structures de Données
EncodeJob (nouveau)
pub struct EncodeJob {
pub track_id: Uuid,
pub input_path: PathBuf,
pub output_dir: PathBuf,
pub codec: AudioCodec,
pub bitrate: u32,
pub quality: String, // "low", "medium", "high", "hi_res"
}
EncoderWorker (nouveau)
pub struct EncoderWorker {
id: usize,
receiver: async_channel::Receiver<EncodeJob>,
db_pool: PgPool,
}
Tables SQL
stream_jobs: id, track_id, status, created_at, updated_at, error_messagestream_segments: id, track_id, quality, segment_index, path, duration, created_at
2.3. Mapping Qualité → Codec/Bitrate
| Qualité | Codec | Bitrate | Sample Rate | Channels | HLS Segment Time |
|---|---|---|---|---|---|
low |
AAC | 64kbps | 22.05kHz | 1 (mono) | 4s |
medium |
AAC | 128kbps | 44.1kHz | 2 (stereo) | 4s |
high |
AAC | 192kbps | 44.1kHz | 2 (stereo) | 4s |
hi_res |
AAC | 320kbps | 48kHz | 2 (stereo) | 4s |
Note: Opus pourra être ajouté plus tard pour ultra-low latency.
3. PLAN D'IMPLÉMENTATION
Phase 1: Infrastructure de Base
- ✅ Créer migrations SQL (
stream_jobs,stream_segments) - ✅ Créer
EncodeJobdanssrc/core/job.rs - ✅ Améliorer
FfmpegCommandBuilder(ajouter-threads 1,-map 0:a)
Phase 2: Pool d'Encodeurs
- ✅ Implémenter
EncoderWorkeravec queue async_channel - ✅ Implémenter
EncoderPoolavec spawn workers - ✅ Intégrer capture stderr FFmpeg en streaming
Phase 3: Pipeline Complet
- ✅ Service d'encodage (vérification track, création répertoires)
- ✅ Parsing manifest HLS et insertion segments en DB
- ✅ Mise à jour
stream_jobsstatus
Phase 4: API REST
- ✅ Handlers API (encode, status, HLS manifest, segments)
- ✅ Intégration dans router principal
Phase 5: Tests & Documentation
- ✅ Tests unitaires (command builder, progress parser)
- ✅ Tests d'intégration (mini audio file, vérification HLS)
- ✅ Documentation technique complète
4. DÉPENDANCES REQUISES
- ✅
async-channel: Queue async pour jobs - ✅
tokio::process::Command: Spawn FFmpeg - ✅
sqlx: DB operations - ✅
uuid: IDs - ✅
tracing: Logging - ✅
regex: Parsing stderr FFmpeg (déjà présent)
FFmpeg système:
- Doit être installé:
sudo apt-get install ffmpeg - Version minimale: 4.0+
5. RISQUES IDENTIFIÉS
-
Performance CPU
- FFmpeg peut saturer CPU si trop de workers
- MITIGATION: Limiter à
min(nb_cpu / 2, 8)
-
Espace disque
- Segments HLS peuvent être volumineux
- MITIGATION: Cleanup automatique après X jours (future feature)
-
FFmpeg non disponible
- Erreur si FFmpeg pas installé
- MITIGATION: Vérifier au démarrage, retourner erreur claire
-
Concurrence DB
- Plusieurs workers insèrent segments simultanément
- MITIGATION: Transactions, index sur (track_id, quality, segment_index)
6. CRITÈRES DE SUCCÈS
- Pool d'encodeurs fonctionnel avec workers FFmpeg réels
- Segments HLS générés et accessibles via API
- API
/stream/:track_id/:quality/index.m3u8opérationnelle - Logs
tracingcomplets (avancement, erreurs, temps) - DB mise à jour correctement (
stream_jobs,stream_segments) - Worker pool robuste & stable (pas de leaks, gestion erreurs)
- Documentation complète (
docs/STREAM_ENCODING_PIPELINE.md) - TRIAGE.md mis à jour (P0 Streaming résolu)
Prochaine étape: Implémentation Phase 1 (Infrastructure de Base)