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 KiB
7 KiB
🎯 DESIGN - Pipeline d'encodage audio minimal mais robuste
Date: 2025-01-27
Mission: P0 - Rendre le stream-server fonctionnel
1. ARCHITECTURE
1.1 Vue d'ensemble
┌─────────────────┐
│ API Routes │
│ /transcode │
│ /job/{id} │
│ /hls/{id}/... │
└────────┬────────┘
│
▼
┌─────────────────┐
│ TranscodingEngine│
│ - Queue │
│ - JobManager │
│ - WorkerPool │
└────────┬────────┘
│
▼
┌─────────────────┐
│ Worker Pool │
│ (N workers) │
└────────┬────────┘
│
▼
┌─────────────────┐
│ FFmpeg Process │
│ (HLS output) │
└─────────────────┘
1.2 Composants principaux
TranscodingEngine
- Responsabilité: Orchestrer le transcodage
- Composants:
PriorityQueue: File d'attente des jobsJobManager: Stockage et suivi des jobsWorkerPool: Pool de workers parallèles
JobManager
- Responsabilité: Stocker et suivre l'état des jobs
- Stockage:
HashMap<Uuid, TranscodingJob>(en mémoire pour P0) - Méthodes:
enqueue(job) -> Uuidget_status(job_id) -> Option<JobStatus>update_status(job_id, status)
WorkerPool
- Responsabilité: Traiter les jobs en parallèle
- Implémentation: Tokio tasks avec canal async
- Workers: N workers (configurable, défaut:
num_cpus())
Pipeline
- Responsabilité: Exécuter FFmpeg et gérer les erreurs
- Fonction:
transcode_to_hls(input_path, output_dir, codec, bitrate) -> Result<TranscodeResult>
2. PIPELINE D'ENCODAGE
2.1 Fonction principale
async fn transcode_to_hls(
input_path: &Path,
output_dir: &Path,
codec: AudioCodec,
bitrate: u32,
profile: &QualityProfile,
) -> Result<TranscodeResult, TranscodeError>
Étapes:
- Créer le répertoire de sortie
{output_dir}/{job_id}/ - Construire la commande FFmpeg
- Exécuter FFmpeg avec timeout
- Vérifier que
index.m3u8et segments existent - Retourner
TranscodeResultavec chemins
2.2 Structure de sortie HLS
{output_dir}/
{job_id}/
index.m3u8 # Master playlist HLS
segment_00001.ts
segment_00002.ts
segment_00003.ts
...
2.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
...
#EXT-X-ENDLIST
3. COMMAND BUILDER FFMPEG
3.1 Arguments par codec
AAC
ffmpeg -i input.wav \
-c:a aac \
-b:a 192k \
-ar 44100 \
-ac 2 \
-f hls \
-hls_time 6 \
-hls_playlist_type vod \
-hls_segment_filename segment_%05d.ts \
index.m3u8
MP3
ffmpeg -i input.wav \
-c:a libmp3lame \
-b:a 192k \
-ar 44100 \
-ac 2 \
-f hls \
-hls_time 6 \
-hls_playlist_type vod \
-hls_segment_filename segment_%05d.ts \
index.m3u8
Opus
ffmpeg -i input.wav \
-c:a libopus \
-b:a 192k \
-ar 48000 \
-ac 2 \
-f hls \
-hls_time 6 \
-hls_playlist_type vod \
-hls_segment_filename segment_%05d.ts \
index.m3u8
FLAC
ffmpeg -i input.wav \
-c:a flac \
-compression_level 5 \
-ar 44100 \
-ac 2 \
-f hls \
-hls_time 6 \
-hls_playlist_type vod \
-hls_segment_filename segment_%05d.ts \
index.m3u8
3.2 Améliorations du builder
- ✅ Ajouter
-hls_list_size 0pour VOD (liste complète) - ✅ Valider que FFmpeg est installé au démarrage
- ✅ Gérer les erreurs de construction de commande
4. GESTION DES ERREURS
4.1 Types d'erreurs
#[derive(Debug, thiserror::Error)]
pub enum TranscodeError {
#[error("Input file not found: {0}")]
InputNotFound(PathBuf),
#[error("FFmpeg execution failed: {0}")]
FfmpegError(String),
#[error("Transcoding timed out after {0} seconds")]
Timeout(u64),
#[error("Output directory creation failed: {0}")]
OutputDirError(String),
#[error("HLS manifest not generated")]
ManifestMissing,
#[error("Insufficient disk space")]
DiskSpaceError,
}
4.2 Gestion du timeout
- Timeout: 5 minutes par défaut
- Action: Tuer le processus FFmpeg si timeout
- Implémentation: Utiliser
Command::kill()sur le child process
4.3 Retry logic
- Max retries: 3
- Conditions de retry:
- Erreur temporaire (timeout, IO error)
- Pas de retry sur erreur permanente (fichier corrompu)
5. API REST
5.1 POST /v1/stream/transcode
Request:
{
"file": "<multipart file>",
"codec": "aac",
"bitrate": 192000,
"quality_profile": "high"
}
Response:
{
"job_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "queued",
"message": "Job submitted successfully"
}
5.2 GET /v1/stream/job/{id}
Response:
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"status": "processing",
"progress": 45.5,
"created_at": "2025-01-27T10:00:00Z",
"started_at": "2025-01-27T10:00:05Z",
"completed_at": null,
"error": null
}
5.3 GET /v1/stream/hls/{job_id}/index.m3u8
Response: Contenu du fichier index.m3u8 avec Content-Type: application/vnd.apple.mpegurl
5.4 GET /v1/stream/hls/{job_id}/{segment}
Response: Contenu binaire du segment .ts avec Content-Type: video/mp2t
6. INTÉGRATION DANS APPSTATE
6.1 Ajout de TranscodingEngine
pub struct AppState {
// ... existing fields ...
pub transcoding_engine: Arc<TranscodingEngine>,
}
6.2 Initialisation dans AppState::new()
let transcoding_engine = Arc::new(
TranscodingEngine::new(num_cpus::get())
);
transcoding_engine.start();
7. LOGS STRUCTURÉS
7.1 Événements à logger
job_queued: Job soumisjob_started: Worker commence le traitementjob_progress: Progression (toutes les 10%)job_completed: Job terminé avec succèsjob_failed: Job échoué avec erreur
7.2 Format des logs
tracing::info!(
job_id = %job.id,
status = "queued",
priority = ?job.priority,
"Job queued for transcoding"
);
8. TESTS
8.1 Tests unitaires
- ✅ Test command builder pour chaque codec
- ✅ Test pipeline avec fichier WAV de test
- ✅ Test job manager en mémoire
8.2 Tests d'intégration
- ✅ Upload fichier → job → index.m3u8 généré
- ✅ Vérification existence segments
- ✅ Test timeout FFmpeg
9. LIMITATIONS P0
- ❌ Pas de multi-bitrate adaptatif (ABR)
- ❌ Pas de DRM
- ❌ Pas de persistance en base de données (mémoire uniquement)
- ❌ Pas de métriques Prometheus détaillées
- ❌ Pas de cleanup automatique des anciens jobs
Prochaine étape: Phase 3 - Implémentation