web-dev-qa-db-fra.com

API Web Audio pour la diffusion en direct?

Nous devons diffuser de l'audio en direct (à partir d'un appareil médical) vers des navigateurs Web avec pas plus de 3 à 5 secondes de retard de bout en bout (supposons 200 ms ou moins de latence du réseau). Aujourd'hui, nous utilisons un plugin de navigateur (NPAPI) pour le décodage , filtrage (haut, bas, bande) et lecture du flux audio ( livrés via Web Sockets).

Nous voulons remplacer le plugin.

Je regardais divers démos Web Audio API et la plupart de nos fonctionnalités requises (lecture, contrôle de gain, filtrage) semblent être disponibles dans Web Audio API . Cependant, il n'est pas clair pour moi si l'API Web Audio peut être utilisée pour les sources diffusées car la plupart de l'API Web Audio utilise des sons courts et/ou des clips audio.

L'API Web Audio peut-elle être utilisée pour lire de l'audio en direct?

Mise à jour (11-févr.-2015):

Après un peu plus de recherches et de prototypage local, je ne suis pas sûr que le streaming audio en direct avec Web Audio API soit possible. Comme l'API Web Audio decodeAudioData n'est pas vraiment conçu pour gérer des morceaux aléatoires de données audio (dans notre cas, livrés via WebSockets). Il semble avoir besoin de tout le "fichier" pour le traiter correctement.

Voir stackoverflow:

Il est maintenant possible avec createMediaElementSource de connecter un élément <audio> À l'API Web Audio, mais mon expérience a montré que le <audio> Induit une énorme quantité de retard de bout en bout (15-30s) et il ne semble pas y avoir de moyen de réduire le retard à moins de 3-5 secondes.

I pensez la seule solution est d'utiliser WebRTC avec l'API Web Aduio. J'espérais éviter WebRTC car cela nécessitera des modifications importantes de notre implémentation côté serveur.

Mise à jour (12-févr.-2015) Partie I :

Je n'ai pas complètement éliminé la balise <audio> (Besoin de terminer mon prototype). Une fois que je l'ai exclu, je soupçonne que le createScriptProcessor (obsolète mais toujours pris en charge) sera un bon choix pour notre environnement car je pourrais `` diffuser '' (via WebSockets) nos données ADPCM vers le navigateur, puis (en JavaScript) le convertir en PCM. Similaire à ce que fait la bibliothèque de Scott (voir ci-dessous) en utilisant le createScriptProcessor. Cette méthode ne nécessite pas que les données soient dans des "morceaux" correctement dimensionnés et un timing critique comme l'approche decodeAudioData.

Mise à jour (12 février 2015) Partie II :

Après plus de tests, j'ai éliminé l'interface <audio> Vers l'API Web Audio car, selon le type de source, la compression et le navigateur, le délai de bout en bout peut être de 3 à 30 secondes. Cela laisse la méthode createScriptProcessor (voir l'article de Scott ci-dessous) ou WebRTC. Après avoir discuté avec nos décideurs, il a été décidé que nous adopterions l'approche WebRTC. I supposez cela fonctionnera. Mais cela nécessitera des modifications de notre code côté serveur.

Je vais marquer la première réponse, juste pour que la "question" soit fermée.

Merci pour l'écoute. N'hésitez pas à ajouter des commentaires au besoin.

40
Tony

Oui, l'API Web Audio (avec AJAX ou Websockets) peut être utilisée pour le streaming.

Fondamentalement, vous tirez vers le bas (ou envoyez, dans le cas des Websockets) des morceaux de longueur n. Ensuite, vous les décodez avec l'API Web Audio et vous les mettez en file d'attente pour les lire, l'un après l'autre.

Parce que l'API Web Audio a une synchronisation de haute précision, vous n'entendrez pas de "coutures" entre la lecture de chaque tampon si vous effectuez la programmation correctement.

7
Kevin Ennis

J'ai écrit un système d'API Web Audio en streaming où j'ai utilisé des travailleurs Web pour faire toute la gestion des sockets Web pour communiquer avec node.js de telle sorte que le thread du navigateur rend simplement l'audio ... fonctionne très bien sur les ordinateurs portables, car les mobiles sont en retard dans leur mise en œuvre de sockets Web à l'intérieur des travailleurs Web, vous avez besoin de pas moins de Lollipop pour qu'il fonctionne comme codé ... J'ai posté code source complet ici

4
Scott Stensland

Pour développer les commentaires sur la façon de lire un tas de tampons séparés stockés dans un tableau en déplaçant le dernier à chaque fois:

Si vous créez un tampon via createBufferSource(), il contient un événement onended auquel vous pouvez attacher un rappel, qui se déclenchera lorsque le tampon aura atteint sa fin. Vous pouvez faire quelque chose comme ça pour jouer les différents morceaux du tableau les uns après les autres:

function play() {
  //end of stream has been reached
  if (audiobuffer.length === 0) { return; }
  let source = context.createBufferSource();

  //get the latest buffer that should play next
  source.buffer = audiobuffer.shift();
  source.connect(context.destination);

  //add this function as a callback to play next buffer
  //when current buffer has reached its end 
  source.onended = play;
  source.start();
}

J'espère que ça t'as aidé. J'expérimente toujours sur la façon de rendre tout cela fluide et aplani, mais c'est un bon début et il manque dans de nombreux articles en ligne.

0
worker11811