Comparaison des codecs, protocoles de streaming et architectures pour Veza. Informe les choix techniques du stream server Rust (Axum). Date : 27 mars 2026.
| Codec | Type | Bitrate typique | Latence | Qualité perçue | Licence | Usage Veza |
|---|---|---|---|---|---|---|
| Opus | Lossy | 64-256 kbps | 5-66 ms | Excellente (transparent à 128 kbps) | BSD (libre) | WebSocket temps réel |
| AAC-LC | Lossy | 128-256 kbps | ~20 ms | Très bonne | Brevets (gratuit pour decode) | HLS segments |
| MP3 | Lossy | 128-320 kbps | ~50 ms | Bonne | Brevets expirés (libre) | Téléchargement, fallback |
| FLAC | Lossless | 700-1400 kbps | Variable | Parfaite (bit-perfect) | Libre | Stockage source, download premium |
| Vorbis | Lossy | 64-320 kbps | ~20 ms | Bonne | BSD (libre) | Alternative Opus (containers Ogg) |
| WAV | Non compressé | 1411 kbps (16-bit/44.1) | 0 | Parfaite | Libre | Upload source |
Architecture multi-codec :
Upload (WAV/FLAC source)
│
▼
Transcoding (FFmpeg via stream server Rust)
│
├── HLS adaptatif : AAC-LC à 64/128/256 kbps (compatibilité maximale)
├── WebSocket : Opus à 128 kbps (qualité optimale à bas bitrate)
└── Téléchargement : FLAC (lossless) ou MP3 320 (compatibilité)
Pourquoi Opus pour le WebSocket :
Pourquoi AAC-LC pour le HLS :
| Protocole | Latence | Adaptatif | Support navigateur | Complexité serveur | Usage |
|---|---|---|---|---|---|
| HLS (HTTP Live Streaming) | 6-30s | Oui (multi-bitrate) | Universel (natif Safari, HLS.js partout) | Moyen | Streaming audio standard |
| DASH (MPEG-DASH) | 6-30s | Oui (multi-bitrate) | Via dash.js (pas natif) | Moyen | Alternative ouverte à HLS |
| LL-HLS (Low Latency HLS) | 1-3s | Oui | Safari natif, HLS.js partiel | Élevé | Live streaming |
| WebSocket | <100ms | Manuel | Universel | Faible-Moyen | Temps réel (co-écoute, sync) |
| WebRTC | <100ms | Oui (native) | Universel | Élevé (TURN/STUN) | P2P audio (co-écoute future) |
| Icecast/Shoutcast | 2-10s | Non | Via lecteur audio | Faible | Radio/stream continu |
Cas 1 : Lecture standard (playlist, bibliothèque)
→ HLS adaptatif (AAC-LC, segments .ts, playlist .m3u8)
→ Multi-bitrate : 64 / 128 / 256 kbps
→ Client : HLS.js (ou natif Safari)
Cas 2 : Co-écoute synchronisée
→ WebSocket (Opus)
→ Protocole de sync personnalisé (play/pause/seek/heartbeat)
→ Latence cible : <200ms entre participants
Cas 3 : Live streaming (futur)
→ RTMP ingest (OBS → Nginx-RTMP)
→ Transcoding → HLS (LL-HLS si latence critique)
→ Distribution via stream server Rust
| Critère | HLS | DASH |
|---|---|---|
| Support iOS/Safari | Natif | Via JS uniquement |
| Support Android/Chrome | Via HLS.js | Via dash.js |
| Écosystème | Dominant (Apple, FFmpeg) | Plus ouvert mais moins adopté |
| Complexité | Standard, bien documenté | Standard mais fragmenté |
| Outils | FFmpeg supporte nativement | FFmpeg supporte nativement |
| CDN compatible | Tous | Tous |
HLS est le choix pragmatique : support natif Safari + HLS.js partout ailleurs = couverture 100%. DASH n'apporte pas d'avantage justifiant la complexité supplémentaire.
hls/{track_id}/
├── master.m3u8 # Playlist maître (liste les qualités)
├── low/
│ ├── playlist.m3u8 # 64 kbps AAC-LC
│ └── segment_XXX.ts # Segments de 6 secondes
├── medium/
│ ├── playlist.m3u8 # 128 kbps AAC-LC
│ └── segment_XXX.ts
├── high/
│ ├── playlist.m3u8 # 256 kbps AAC-LC
│ └── segment_XXX.ts
└── lossless/ # (optionnel, pour abonnés premium)
├── playlist.m3u8 # FLAC
└── segment_XXX.ts
Le stream server Rust implémente une sélection adaptative :
medium (128 kbps)highlow immédiatement# Qualité basse (64 kbps) {#qualite-basse-64-kbps}
ffmpeg -i input.wav -c:a aac -b:a 64k -ar 44100 -ac 2 \
-hls_time 6 -hls_list_size 0 -hls_segment_filename 'low/segment_%03d.ts' \
low/playlist.m3u8
# Qualité moyenne (128 kbps) {#qualite-moyenne-128-kbps}
ffmpeg -i input.wav -c:a aac -b:a 128k -ar 44100 -ac 2 \
-hls_time 6 -hls_list_size 0 -hls_segment_filename 'medium/segment_%03d.ts' \
medium/playlist.m3u8
# Qualité haute (256 kbps) {#qualite-haute-256-kbps}
ffmpeg -i input.wav -c:a aac -b:a 256k -ar 48000 -ac 2 \
-hls_time 6 -hls_list_size 0 -hls_segment_filename 'high/segment_%03d.ts' \
high/playlist.m3u8
| Étape | Latence | Cumulé |
|---|---|---|
| Encodage Opus (client A) | 20 ms | 20 ms |
| Transmission WebSocket | 10-50 ms | 30-70 ms |
| Décodage Opus (client B) | 20 ms | 50-90 ms |
| Buffer de jitter | 50 ms | 100-140 ms |
| Total | 100-140 ms |
La co-écoute synchronisée est viable avec un décalage perceptible de <200 ms. Au-delà, les participants perçoivent un décalage gênant.
Le stream server utilise un protocole de sync via WebSocket :
Host envoie position → Serveur redistribue → Participants ajustent
↓
Tolérance : ±200ms
Si écart > 200ms : resync forcé
Heartbeat : 30s
| Format | Taille | Bande passante nécessaire |
|---|---|---|
| WAV source (24-bit) | ~63 Mo | N/A (upload seul) |
| FLAC | ~25 Mo | 700-1400 kbps |
| HLS high (256 kbps AAC) | ~7.5 Mo | 256 kbps |
| HLS medium (128 kbps AAC) | ~3.8 Mo | 128 kbps |
| HLS low (64 kbps AAC) | ~1.9 Mo | 64 kbps |
| Total par piste (tous formats) | ~101 Mo |
| Métrique | Valeur |
|---|---|
| Bande passante disponible | 1 Gbps ≈ 125 Mo/s |
| Flux simultanés (128 kbps) | ~7 800 |
| Flux simultanés (256 kbps) | ~3 900 |
| Stockage MinIO (HDD 1.8 To, ZFS mirror = 900 Go utile) | ~9 000 pistes |
Pour les premiers 200-500 utilisateurs actifs, la capacité est largement suffisante.
| Format | Extension | Priorité | Notes |
|---|---|---|---|
| WAV | .wav | Principal | Non compressé, meilleure source pour transcoding |
| FLAC | .flac | Principal | Lossless, économise la bande passante upload |
| AIFF | .aiff | Secondaire | Équivalent WAV (Apple) |
| MP3 | .mp3 | Accepté | Lossy — transcoding depuis lossy non idéal |
| OGG/Vorbis | .ogg | Accepté | Libre |
| AAC/M4A | .m4a, .aac | Accepté | Lossy |
Recommandation à l'utilisateur : uploader en WAV ou FLAC pour la meilleure qualité de transcoding.
Avantage : réduirait la charge serveur (le stream passe directement entre participants). Inconvénient : complexité (STUN/TURN), NAT traversal, incompatibilité derrière certains firewalls. Verdict : pas pour le MVP. Le WebSocket centralisé est suffisant et plus fiable.
HLS supporte officiellement les segments audio en fragmented MP4 (fMP4) avec codec Opus depuis 2020. Avantage : meilleure qualité à bas bitrate que AAC. Inconvénient : support Safari limité (iOS 17+). Verdict : à surveiller. Quand Safari ≥17 sera dominant (estimé 2027), migrer de AAC vers Opus dans HLS.
Pour un futur tier premium : streaming FLAC via segments HLS fMP4. Apple Music et Tidal le font déjà. Nécessite : bande passante client ≥1.5 Mbps, stockage serveur ×3. Verdict : pertinent pour un tier payant futur. Pas prioritaire pour le lancement.