使用Node.js和WebSockets进行流式二进制

时间:2013-03-26 13:21:06

标签: node.js websocket

我一直在谷歌搜索这个并查看stackoverflow一段时间但没有找到解决方案 - 因此发布。

出于好奇,我正在玩Node.js和WebSockets。我正在尝试将一些二进制数据(一个mp3)传输到客户端。到目前为止我的代码在下面,但显然没有按预期工作。

我怀疑我的问题是我实际上并没有从服务器发送二进制数据,并希望得到一些澄清/帮助。

继承我的服务器......

var fs = require('fs');
var WebSocketServer = require('ws').Server;

var wss = new WebSocketServer({port: 8080,host:"127.0.0.1"});
wss.on('connection', function(ws) {    
    var readStream = 
    fs.createReadStream("test.mp3", 
     {'flags': 'r',
      'encoding': 'binary', 
      'mode': 0666, 
      'bufferSize': 64 * 1024});

    readStream.on('data', function(data) {
        ws.send(data, {binary: true, mask: false});
    });
});

我的客户......

context = new webkitAudioContext();
var ws = new WebSocket("ws://localhost:8080");
ws.binaryType = 'arraybuffer';

ws.onmessage = function (evt) {
    context.decodeAudioData(
    evt.data,
        function(buffer) {
            console.log("Success");
        }, 
        function(error) {
            console.log("Error");
        });
};

解码调用总是在错误回调中结束。我假设这是因为它收到了错误的数据。

所以我的问题是如何正确地将文件作为二进制文件流传输?

由于

2 个答案:

答案 0 :(得分:3)

您的服务器正在做的是它将包含64 KB块的二进制音频数据的消息发送到您的客户端。您的客户端应该在调用decodeAudioData之前重建音频文件。

每次客户端在websocket上收到消息时,您都在调用decodeAudioData。您必须创建一个单独的缓冲区来向其添加所有块。然后在传输完成时,缓冲区应输入decodeAudioData

您现在有两个选择:

  1. 您在不使用流事件的情况下加载整个文件(fs.read)并使用ws.send发送整个文件(易于操作)
  2. 您使用流事件,修改您的客户端以接受数据块并在调用decodeAudioData之前汇总它们

答案 1 :(得分:0)

问题解决了。

我通过从传递给“createReadStream()”的选项中删除“'encoding':'binary'”参数和解决方案来解决这个问题...

decodeAudioData returning a null error

根据我的一些评论,当我更新createReadStream选项时,第一个块正在播放,但所有其他块正在从decodeAudioData()执行onError回调。上面链接中的解决方案为我解决了这个问题。 似乎decodeAudioData()有点挑剔它接收的块应该如何格式化。它们应该是有效的块...

Define 'valid mp3 chunk' for decodeAudioData (WebAudio API)