it-swarm.com.de

Wie streame ich MP3-Daten über WebSockets mit node.js und socket.io?

Ich habe Probleme beim Streaming von MP3-Daten über WebSocket mit node.js und socket.io. Alles scheint zu funktionieren, aber decodeAudioData spielt mit mir nicht fair.

Das ist mein Spielzeugserver:

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/');

Der Client empfängt die Daten als Typzeichenfolge, aber ich möchte die Daten decodeAudioData zuführen, und es scheint, dass es keine Zeichenfolgen mag. Der Aufruf von decodeAudioData führt zu folgender Fehlermeldung:

Uncaught Error: SYNTAX_ERR: DOM Exception 12

Ich denke, decodeAudioData benötigt die in einem ArrayBuffer gespeicherten Daten. Gibt es eine Möglichkeit, die Daten zu konvertieren?

Dies ist der Client-Code:

<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>
18
Jan Deinhard

Ich habe selbst eine Möglichkeit gefunden, MP3-Daten über Websockets zu streamen.

Ein Problem war die Blockgröße der MP3-Daten. Es scheint, dass die Web-Audio-API mit gültigen MP3-Chunks gespeist werden muss, um die Daten dekodieren zu können. Wahrscheinlich nicht überraschend. In meiner Demo-App stelle ich eine Reihe von MP3-Chunk-Dateien bereit.

Auch die Audioqualität ist nicht perfekt. Ich habe einige subtile Störungen. Ich konnte das verbessern, indem ich größere Stücke von MP3-Daten verschickte, aber es gibt immer noch winzige Knistern.

EDIT: Ich habe es geschafft, die Audioqualität zu verbessern. Es scheint, dass die Web-Audio-Methode decodeAudioData nicht wirklich zum Decodieren von fortlaufenden Teilen von MP3-Daten entwickelt wurde.

11
Jan Deinhard

In Ihrem Fall, in dem context.decodeAudioData einen ArrayBuffer der Binärdaten erwartet, würde ich vorschlagen, Ihren Chunk in einen base64-String und dann in einen ArrayBuffer-Client zu konvertieren, um die vorhersagbarsten Ergebnisse zu erzielen. Dieses Skript sollte ein guter Ausgangspunkt für die clientseitige Dekodierung von base64 der aufgeteilten Daten sein.

Das Hinzufügen einer Zeile mit data = Base64Binary.decodeArrayBuffer(data); direkt nach dem Abrufen Ihrer Daten (Base-64-codierte Zeichenfolge) würde den Trick tun ...

3
Tracker1

Es scheint, dass socket.io die binäre Übertragung immer noch nicht unterstützt. Also websocket.io kann hier verwendet werden.

  1. https://github.com/LearnBoost/socket.io/issues/511#issuecomment-2370129
  2. https://github.com/LearnBoost/socket.io/issues/680#issuecomment-3083490
0
Anant Gupta