Comment diffuser des données MP3 via les WebSockets avec node.js et de la prise.io?
J'ai des problèmes de streaming MP3 de données via WebSocket avec node.js et de la prise.io. Tout semble fonctionner mais decodeAudioData ne joue pas juste avec moi.
C'est mon jouet serveur:
var app = require('http').createServer(handler)
, io = require('socket.io').listen(app)
, fs = require('fs')
app.listen(8081);
function handler (req, res) {
res.writeHead(200, {
'Content-Type': 'text/html',
});
res.end('Hello, world!');
}
io.configure('development', function() {
io.set('log level', 1);
io.set('transports', [ 'websocket' ]);
});
io.sockets.on('connection', function (socket) {
console.log('connection established');
var readStream = fs.createReadStream("test.mp3",
{'flags': 'r',
'encoding': 'binary',
'mode': 0666,
'bufferSize': 64 * 1024});
readStream.on('data', function(data) {
console.log(typeof data);
console.log('sending chunk of data')
socket.send(data);
});
socket.on('disconnect', function () {
console.log('connection droped');
});
});
console.log('Server running at http://127.0.0.1:8081/');
Le client reçoit les données de type string, mais je veux nourrir les données de decodeAudioData et il semble qu'il n'aime pas les chaînes. L'appel à decodeAudioData résultats dans le message d'erreur suivant:
Uncaught Error: SYNTAX_ERR: DOM Exception 12
Je pense que decodeAudioData besoins les données stockées dans une ArrayBuffer. Est-il un moyen de convertir les données?
C'est le code de client:
<script src="http://127.0.0.1:8081/socket.io/socket.io.js"></script>
<script>
var audioBuffer = null;
var context = null;
window.addEventListener('load', init, false);
function init() {
try {
context = new webkitAudioContext();
} catch(e) {
alert('Web Audio API is not supported in this browser');
}
}
function decodeHandler(buffer) {
console.log(data);
}
var socket = io.connect('http://127.0.0.1:8081');
socket.on('message', function (data) {
//HERE IS THE PROBLEM
context.decodeAudioData(data, decodeHandler, function(e) { console.log(e); });
});
</script>
- avez-vous trouvé une solution à ce problème?
- Je n'ai pas trouvé une solution à l'aide d'une douille.io. Voir ma propre réponse pour une solution sans prise.io.
- Socket.io 1.0 support pour les binaires, j'ai essayer, mais ne fonctionne pas. Aussi, j'ai essayer avec websocket, mais avec exactement la même erreur. Vous avez un exemple de comment vous résoudre ce problème?.
- Ma solution était à l'époque à l'aide de ws au lieu de la Prise.io. Mais je sais que cela fonctionne avec la Prise de courant.io version. Sur le côté serveur, j'ai dû indiquer explicitement ws pour envoyer des données binaires comme
ws.send(array, { binary: true, mask: true });
Pas sûr si j'ai mis un masque à true ou false. HTH - Essayez de supprimer
'encoding': 'binary',
de lacreateReadStream
Vous devez vous connecter pour publier un commentaire.
J'ai trouvé un moyen de flux de données MP3 via les Websockets moi-même.
Un problème était la taille de segment de données MP3. Il semble que l'API Web Audio doit être alimenté avec des valides MP3 morceaux pour être en mesure de décoder les données. Probablement pas surprenant. Dans mon demo app je fournir un ensemble de MP3 morceau fichiers.
Aussi la qualité du son n'est pas parfait. J'ai quelques petites saccades. J'ai été en mesure de l'améliorer, par l'envoi de plus gros morceaux de MP3 de données, mais il y a encore un petit crépite.
EDIT: j'ai réussi à améliorer la qualité audio. Il semble que le Web Audio de la méthode decodeAudioData n'est pas vraiment conçu pour décoder continue de morceaux de données MP3.
Dans votre cas le contexte.decodeAudioData s'attend à une ArrayBuffer des données binaires, je suggère la conversion de votre bloc à une chaîne base64, puis à une ArrayBuffer côté client pour obtenir des résultats prévisibles. Ce script devrait être un bon point de départ pour le côté client de décodage de base64 du bloc de données.
L'ajout d'une ligne avec
data = Base64Binary.decodeArrayBuffer(data);
droit après l'obtention de vos données (codé en base 64 string) ferait l'affaire...ws
module à la place de la prise.io. Au moment de la prise.io n'était pas capable de gérer des données binaires. Vous ne savez pas si c'est toujours le cas.Il semble que socket.io n'est pas toujours le soutien de transfert Binaire. Donc websocket.io peut être utilisé ici.