Recherche Technique — Protocoles Audio et Streaming

Comparaison des codecs, protocoles de streaming et architectures pour Veza. Informe les choix techniques du stream server Rust (Axum). Date : 27 mars 2026.


1. Codecs audio — comparaison

Codecs pertinents pour le streaming musical

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

Recommandation pour Veza

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 :


2. Protocoles de streaming — comparaison

Protocoles pertinents

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

Architecture retenue par Veza (actuelle)

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

Pourquoi HLS et pas DASH

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.


3. HLS adaptatif — détails techniques

Structure des fichiers

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

Sélection adaptative du bitrate

Le stream server Rust implémente une sélection adaptative :

  1. Démarrage : commence en medium (128 kbps)
  2. Monitoring : mesure la bande passante disponible (vitesse de download des segments)
  3. Montée : si bande passante > 2x bitrate actuel pendant 3 segments → passer en high
  4. Descente : si buffer < 3 segments → passer en low immédiatement
  5. Stabilisation : ne pas osciller — hysteresis de 2 segments

Paramètres de transcoding FFmpeg

# 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

4. Latence et co-écoute

Budget de latence pour la co-écoute

É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.

Protocole de synchronisation (implémenté)

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

5. Stockage et bande passante

Estimation par piste (4 minutes, stéréo, 44.1 kHz)

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

Capacité serveur (R720 avec fibre 1 Gbps)

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.


6. Formats d'upload acceptés

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.


7. Pistes de recherche future

WebRTC pour la co-écoute P2P

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.

Opus dans les segments HLS

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.

Streaming lossless adaptatif (MQA / ALAC / FLAC over 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.


Voir aussi