Expertise 02 / 07

Streaming audio

Une écoute continue, en arrière-plan, qui ne coupe jamais.

Prouvé sur :Sydica

Depuis juillet 2024

  • gapless
  • Media Session API
  • Web Audio AnalyserNode
  • préchargement de la piste suivante
  • cache Isar embarqué
  • stale-while-revalidate
  • feed Redis ZSET

Code Mes Rêves

Alexis Kouakou

0:004:17

Lancez la lecture : la forme d'onde se construit à partir du signal réel.

File d'attente

3 titres
  • 4:17
  • 3:22
  • 5:27

Glisser pour réordonner

Contrôles Media Session — écran verrouillé

Code Mes Rêves

Alexis Kouakou

Le service audio tourne en arrière-plan : les contrôles système et les casques Bluetooth pilotent la lecture.

Télémétrie en direct

MP3
Latence de démarrage
Piste suivante préchargée0 %

Déclenché dès la piste courante — une seule piste d'avance.

Tampon disponible
0,0 s
Coupures depuis le début
0
Codec / échantillonnage
MP3 · 48,0 kHz
Débit moyen
192 kb/s

Media Session

Inactive

Contrôles écran verrouillé

Lecture · pause · suivante · précédente

Les morceaux de cette démonstration sont les miens : rien à créditer, et le catalogue Sydica reste chez ses ayants droit.

0
Coupures depuis le début
3
Débits transcodés

AAC

Le mécanisme

Comment ça marche.

Téléversement

piste source

API Laravel

transcodage AAC · 3 débits

CDN

segments audio

Cache Isar embarqué

écoute hors ligne

Feed Redis ZSET

stale-while-revalidate

Client

file d'attente · préchargement N+1 · AnalyserNode

Côté serveur — le catalogue.

Le feed est servi depuis Redis, en ZSET pour le classement et en hash pour les métadonnées, avec une stratégie stale-while-revalidate : on rend immédiatement la version en cache, puis on la rafraîchit en arrière-plan. L'utilisateur ne reste jamais devant un écran vide, et la base n'est pas sollicitée à chaque ouverture.

Côté client — l'enchaînement sans blanc.

La piste suivante est mise en tampon avant la fin de la courante, ce qui supprime le silence à la transition. Le catalogue consulté est mis en cache localement dans une base Isar embarquée : l'application reste navigable hors ligne, et les pistes déjà écoutées restent jouables. Le service audio tourne en arrière-plan, ce qui permet aux contrôles système et aux casques Bluetooth de piloter la lecture.

Les arbitrages

Ce que j'ai écarté, et pourquoi.

Un choix technique sans son coût n'est pas un choix, c'est une préférence.

01

Streamer ou télécharger ?

Le problème

Le streaming pur consomme à chaque écoute et coupe dès que le réseau flanche ; le téléchargement complet occupe le stockage et pose la question des droits.

Les options

Streaming pur · téléchargement complet · streaming avec cache local.

Ce que j'ai choisi

Streaming avec cache local des pistes déjà écoutées, plafonné et purgé en LRU.

Le coût

La première écoute d'un titre reste tributaire du réseau.

02

Combien de pistes précharger ?

Le problème

Précharger la piste suivante supprime le silence à la transition, mais sur une file de vingt titres dont l'auditeur n'en écoutera que trois, dix-sept préchargements sont perdus.

Les options

Aucun préchargement · une piste d'avance · toute la file.

Ce que j'ai choisi

Une seule piste d'avance, déclenchée à 70 % de la piste courante.

Le coût

Un saut manuel rapide dans la file ne bénéficie pas du tampon.

03

Forme d'onde : navigateur ou serveur ?

Le problème

L'AnalyserNode est gratuit mais ne connaît que la portion déjà lue ; une forme d'onde pré-calculée montre tout le morceau mais demande un traitement à l'ingestion et un fichier de plus à servir.

Les options

AnalyserNode côté navigateur · forme d'onde pré-calculée côté serveur.

Ce que j'ai choisi

AnalyserNode, dessiné au fil de la lecture.

Le coût

La forme d'onde n'est pas visible d'emblée sur toute la durée du morceau.

Preuves dans le code

Deux extraits réels.

lib/audio_helpers/audio_handler.dart

Extrait à fournir

lib/audio_helpers/player_invoke.dart

Extrait à fournir

Code Mes Rêves

Alexis Kouakou