首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在Node.js上播放Web Audio API中的PCM流

在Node.js上播放Web Audio API中的PCM流
EN

Stack Overflow用户
提问于 2014-01-02 12:03:59
回答 1查看 11.1K关注 0票数 19

我正在使用web音频api从浏览器流式传输录制的PCM音频。

我正在使用binaryJS (websocket connection)将其流式传输到nodejs服务器,并尝试使用扬声器npm模块在服务器上播放该流。

这是我的委托人。The audio buffers are at first non-interleaved IEEE 32-bit linear PCM with a nominal range between -1 and +1。我选择两个PCM通道中的一个开始并在下面流式传输它。

代码语言:javascript
复制
var client = new BinaryClient('ws://localhost:9000');
var Stream = client.send();

recorder.onaudioprocess = function(AudioBuffer){
    var leftChannel = AudioBuffer.inputBuffer.getChannelData (0);
    Stream.write(leftChannel);
}

现在,我将数据作为缓冲区接收,并尝试将其写入npm包中的speaker对象。

代码语言:javascript
复制
var Speaker = require('speaker');

var speaker = new Speaker({
  channels: 1,          // 1 channel
  bitDepth: 32,         // 32-bit samples
  sampleRate: 48000,     // 48,000 Hz sample rate
  signed:true
});

server.on('connection', function(client){
    client.on('stream', function(stream, meta){
        stream.on('data', function(data){
            speaker.write(leftchannel);
        });
    });
});

结果是我的笔记本电脑的扬声器发出了刺耳的尖叫声,这显然不是正在录制的东西。这也不是反馈。我可以确认客户端上的录制缓冲区是有效的,因为我尝试将它们写入WAV文件,并且播放正常。

有问题的docs for speakerdocs for the AudioBuffer

我已经被这个问题困扰了好几天了。有人能找出哪里出了问题吗?或者提供一种不同的方法?

使用solution更新

首先,我错误地使用了websocket API。我更新了上面的内容以正确使用它。

我需要将音频缓冲区转换为整数数组缓冲区。我选择使用Int16Array。由于给定的音频缓冲区的范围介于1和-1之间,因此只需将其乘以新ArrayBuffer的范围(32767到-32768)即可。

代码语言:javascript
复制
recorder.onaudioprocess = function(AudioBuffer){

    var left = AudioBuffer.inputBuffer.getChannelData (0);

    var l = left.length;
    var buf = new Int16Array(l)

    while (l--) {
        buf[l] = left[l]*0xFFFF;    //convert to 16 bit
    }

    Stream.write(buf.buffer);

}
EN

回答 1

Stack Overflow用户

发布于 2014-01-04 14:34:21

看起来您正在将流作为meta对象发送。

根据文档,BinaryClient.send按顺序接受一个data对象(流)和一个meta对象。stream事件的回调接收第一个参数中的流(作为BinaryStream对象,而不是Buffer)和第二个参数中的meta对象。

您将字符串'channel'作为流传递给send(),并将来自getChannelData()Float32Array作为元对象传递给它。如果您将这两个参数互换(或者只使用client.send(leftChannel)),然后更改服务器代码,将stream传递给speaker.write而不是leftchannel (可能应该将其重命名为meta,或者如果您不需要它,则将其删除),它可能会起作用。

请注意,由于Float32Array不是流或缓冲区对象,因此BinaryJS可能是try to send it in one chunk。您可能希望改为发送leftChannel.buffer (the ArrayBuffer behind that object)。

请让我知道这是否适用于您;我现在无法测试您的确切设置。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20876152

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档