web-dev-qa-db-fra.com

Obtenez le streaming audio en direct du serveur NodeJS vers les clients

J'ai besoin d'avoir un flux audio en direct en temps réel à partir d'un client vers un serveur vers plusieurs clients d'écoute.

Actuellement, l'enregistrement du client fonctionne et je transmets l'audio via socket.io au serveur. Le serveur reçoit ces données et doit diffuser l'audio (également via socket.io?) Aux clients qui souhaitent écouter ce flux. Elle doit être aussi en temps réel que possible (minimiser les retards).

J'utilise GetUserMedia pour enregistrer le microphone (la compatibilité du navigateur n'est pas importante ici). Je souhaite que les clients utilisent une balise audio HTML5 pour écouter le flux. Les données reçues sur le serveur sont des morceaux (actuellement emballés par 700) emballés dans un blob de type audio/wav.

Voici mon code pour l'envoyer au serveur:

mediaRecorder.ondataavailable = function(e) {
    this.chunks.Push(e.data);
    if (this.chunks.length >= 700)
    {
        this.sendData(this.chunks);
        this.chunks = [];
    }
};
mediaRecorder.sendData = function(buffer) {
    blob = new Blob(buffer, { 'type' : 'audio/wav' });
    socket.emit('voice', blob);
}

Sur le serveur, je peux envoyer les morceaux au client de la même manière comme ceci:

socket.on('voice', function(blob) {
    socket.broadcast.emit('voice', blob);
});

Sur le client, je peux jouer comme ceci:

var audio = document.createElement('audio');
socket.on('voice', function(arrayBuffer) {
    var blob = new Blob([arrayBuffer], { 'type' : 'audio/wav' });
    audio.src = window.URL.createObjectURL(blob);
    audio.play();
});

Cela fonctionne pour le premier blob de morceaux que j'envoie, mais vous n'êtes pas autorisé à continuer à passer à audio.src vers une nouvelle source d'URL, ce n'est donc pas une solution qui fonctionne.

Je pense que je dois créer une sorte de flux sur le serveur que je peux mettre dans la balise audio du HTML5 sur les clients à l'écoute mais je ne sais pas comment. Les blobs reçus avec des morceaux doivent être ajoutés à ce flux en temps réel.

Quelle est la meilleure approche pour y parvenir? Suis-je en train de le faire du microphone client au serveur?

13
Peter van den Broek

Je suis un peu en retard pour la fête ici, mais il semble que l'API audio Web sera votre ami ici, si vous ne l'avez pas déjà terminé. Il vous permet de lire un flux audio directement sur le périphérique de sortie sans vous soucier de l'attacher à un élément audio.

Je cherche à faire la même chose et votre question a répondu à ma question - comment obtenir des données du client au serveur. L'avantage de l'API audio Web est la possibilité d'ajouter des flux ensemble et de lui appliquer des effets audio sur le serveur.

API MDN Web Audio

Les événements io doivent remplacer les données dans un objet tampon audio dans le contexte audio. Le traitement audio peut avoir lieu dans le contexte audio Web nodeJS avant d'être émis sous forme de flux unique vers chaque client.

2
Chris Cook

Vous pouvez modifier audiosrc dynamiquement comme suit (en supposant le type mp3):

<audio id="audio" controls="controls">
    <source id="mp3Source" type="audio/mp3"></source>
        Your browser does not support the audio format.
</audio>

Appelez la fonction suivante chaque fois qu'un événement socket est reçu:

function updateSource() { 
        var audio = document.getElementById('audio');

        var source = document.getElementById('mp3Source');
        source.src= <blob>;

        audio.load(); //call this to just preload the audio without playing
        audio.play(); //call this to play the song right away
    }
1
Aman Gupta