首页 文章

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

提问于
浏览
9

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

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

我怀疑我的问题是我实际上并不是从服务器发送二进制数据而是想要一些 clarification/help。

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

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 回答

  • 3

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

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

    你现在有两个选择:

    • 您在不使用流事件的情况下加载整个文件(fs.read)并使用 ws.send 发送整个文件(很容易)

    • 您使用流事件,修改您的客户端以接受数据块并在调用decodeAudioData之前汇编它们

  • 0

    问题解决了。

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

    decodeAudioData 返回 null 错误

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

    为 decodeAudioData 定义'有效的 mp3 块'(WebAudio API)

相关问题