J'ai programmé un serveur qui crée un flux audio à partir de l'entrée audio de mon MacBook, en utilisant express , osx-audio et lame :
const http = require("http");
const express = require("express");
const audio = require("osx-audio");
const lame = require("lame");
const audioInput = new audio.Input();
const encoder = new lame.Encoder({
channels: 2,
bitDepth: 16,
sampleRate: 44100,
bitRate: 128,
outSampleRate: 22050,
mode: lame.STEREO
});
audioInput.pipe(encoder);
const app = express();
const server = http.Server(app);
app.get("/stream.mp3", (req, res) => {
res.set({
"Content-Type": "audio/mpeg",
"Transfer-Encoding": "chunked"
});
encoder.pipe(res);
});
server.listen(3000);
Côté client, le son de ce flux audio est inclus comme un élément <audio> comme ceci:
<audio controls autoplay preload="none">
<source src="./stream.mp3" type="audio/mpeg" />
<p>Oops – your browser doesn't support HTML5 audio!</p>
</audio>
Cela fonctionne - je peux entendre le son de la source d'entrée que j'ai sélectionnée sur mon ordinateur portable à partir de n'importe quel navigateur connecté au serveur lorsque je clique sur le bouton "play" de l'élément audio.
Cependant l'audio lu par le navigateur est en retard de quelques secondes sur le signal d'origine. Il semble bien que j'utilise preload="none"
, le navigateur met en mémoire tampon une bonne partie du flux audio avant de commencer à le lire.
Y a-t-il quelque chose d'évident qui manque ici? Existe-t-il un meilleur moyen d'obtenir un son en temps réel avec seulement quelques millisecondes de latence au lieu de plusieurs secondes?
Si vous êtes intéressé, le code source complet de mon projet est ici sur GitHub .
Plutôt que de réinventer la roue, vous pouvez utiliser FFMPEG , annoncé comme "une solution complète et multiplateforme pour enregistrer, convertir et diffuser du contenu audio et vidéo".
Exemple:
ffmpeg -re -i input -f rtsp -muxdelay 0.1 rtsp://server/live.sdp
Vous pouvez choisir la bibliothèque (h.264, mpeg, etc.) avec laquelle votre navigateur est OK.