# 🔍 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)

- **`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 1` pour isolation CPU
  - **MANQUE**: Option `-map 0:a` pour forcer audio-only
  - **MANQUE**: Pattern de nommage segments personnalisable

#### `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 `String` pour `track_id` au lieu de `Uuid`

- **`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.rs`** et **`queue.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_id` au lieu de `track_id` + `quality`

### 1.2. Ce Qui Manque Totalement ❌

1. **Pool d'encodeurs fonctionnel**
   - Aucun worker thread réel
   - Aucune queue async_channel
   - Aucun spawn de processus FFmpeg

2. **Structure `EncodeJob`**
   - Pas de structure dédiée pour encodage (utilise `TranscodingJob` qui est générique)
   - Pas de mapping qualité → codec/bitrate automatique

3. **Pipeline d'encodage complet**
   - Pas de vérification `track.source_path` en 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`)

4. **Migrations SQL**
   - Table `stream_jobs` n'existe pas
   - Table `stream_segments` n'existe pas
   - Pas d'index pour performance

5. **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)

6. **Monitoring FFmpeg**
   - Pas de capture stderr en streaming
   - Pas de logs tracing pour avancement
   - Pas de détection crashes FFmpeg

7. **Parsing segments HLS**
   - Pas de parsing du manifest `.m3u8` pour extraire segments
   - Pas de calcul durée par segment
   - Pas de validation segments générés

### 1.3. Incohérences / À Refactor ⚠️

1. **Duplication structures**
   - `src/core/encoder.rs` : `EncoderPool`, `EncoderPipeline` (abstrait, traits)
   - `src/transcoding/pipeline/` : `TranscodingJob`, `TranscodingWorker` (concret, FFmpeg)
   - **SOLUTION**: Utiliser `TranscodingJob` comme base, créer `EncodeJob` wrapper si besoin

2. **Conventions MIME / Format**
   - `AudioCodec` dans `core/encoder.rs` (enum avec variants)
   - `AudioCodec` dans `transcoding/codecs/mod.rs` (enum simple)
   - **SOLUTION**: Unifier vers `transcoding/codecs/mod.rs`

3. **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

4. **Handling erreurs FFmpeg**
   - `TranscodingWorker` capture 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

5. **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

---

## 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)
```rust
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)
```rust
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_message
- `stream_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
1. ✅ Créer migrations SQL (`stream_jobs`, `stream_segments`)
2. ✅ Créer `EncodeJob` dans `src/core/job.rs`
3. ✅ Améliorer `FfmpegCommandBuilder` (ajouter `-threads 1`, `-map 0:a`)

### Phase 2: Pool d'Encodeurs
4. ✅ Implémenter `EncoderWorker` avec queue async_channel
5. ✅ Implémenter `EncoderPool` avec spawn workers
6. ✅ Intégrer capture stderr FFmpeg en streaming

### Phase 3: Pipeline Complet
7. ✅ Service d'encodage (vérification track, création répertoires)
8. ✅ Parsing manifest HLS et insertion segments en DB
9. ✅ Mise à jour `stream_jobs` status

### Phase 4: API REST
10. ✅ Handlers API (encode, status, HLS manifest, segments)
11. ✅ Intégration dans router principal

### Phase 5: Tests & Documentation
12. ✅ Tests unitaires (command builder, progress parser)
13. ✅ Tests d'intégration (mini audio file, vérification HLS)
14. ✅ 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

1. **Performance CPU**
   - FFmpeg peut saturer CPU si trop de workers
   - **MITIGATION**: Limiter à `min(nb_cpu / 2, 8)`

2. **Espace disque**
   - Segments HLS peuvent être volumineux
   - **MITIGATION**: Cleanup automatique après X jours (future feature)

3. **FFmpeg non disponible**
   - Erreur si FFmpeg pas installé
   - **MITIGATION**: Vérifier au démarrage, retourner erreur claire

4. **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.m3u8` opérationnelle
- [ ] Logs `tracing` complets (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)

