当前位置: 首页 > 知识库问答 >
问题:

在Node.js上播放来自Web Audio API的PCM流

龙越彬
2023-03-14

我正在流式录制的PCM音频从一个浏览器与web音频API。

我正在用binaryJS(websocket连接)将它流到一个nodejs服务器上,并尝试使用speaker npm模块在服务器上播放该流。

这是我的当事人。音频缓冲器首先是非交错的IEEE 32位线性PCM,标称范围在-1至+1之间。我从两个PCM频道中的一个开始,并在下面进行流式传输。

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对象。

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文件,并且它很好地回放了。

扬声器的文档和音频缓冲区的文档

我被这事难住好几天了。有人能找出问题所在或者提供一个不同的方法吗?

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

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

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

}

共有1个答案

权承
2023-03-14

看起来像是作为meta对象发送流。

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

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

注意,由于float32array不是流或缓冲区对象,所以BinaryJS可能尝试在一个块中发送它。您可能希望发送leftchannel.buffer(该对象后面的arraybuffer)。

让我知道这对你有用吗;我现在无法测试你的精确设置。

 类似资料:
  • 问题内容: 我的PCM样本很短。发挥这种效果的最佳方法是什么?格式为8000Hz,单声道,16位,大字节序。(PCM样本是在代码中生成的,而不是通过某些文件读取的) 谢谢 问题答案: 使用javax.sound.sampled包,它非常简单,但是您必须使用一些样板文件。 这是一个很好的教程:www.wikijava.org/wiki/Play_a_wave_sound_in_Java 基本上,您必

  • 我们正在尝试使用从HLS流中捕获的PCM数据进行处理,最好是在播放之前,尽管之后是可以接受的。我们希望在仍然使用AVPlayer的情况下完成所有这些工作。 有人这样做过吗?对于非HLS流以及本地文件,这似乎可以通过MPAudioProcessingTap实现,但不能通过HLS实现。本期讨论如何使用非HLS:AVFoundation音频处理,使用AVPlayer的MTAudioProcessingT

  • 本文向大家介绍使用WindowsAPI实现播放PCM音频的方法,包括了使用WindowsAPI实现播放PCM音频的方法的使用技巧和注意事项,需要的朋友参考一下 本文介绍了使用WindowsAPI实现播放PCM音频的方法,同前面一篇使用WindowsAPI获取录音音频的方法原理具有相似之处,这里就不再详细介绍具体的函数与结构体的参数,相同的部分加以省略,只介绍主要的功能部分代码。如下所示: 1. w

  • 我在java中使用akka,并在akka演员中寻找一种使用异步播放WS api的方法。 在播放WS 2.4.x中,方法返回一个,该可以很容易地转换为Scala,然后用传递到某个akka参与者,以便将http响应作为akka消息接收。 在播放WS 2.5.x中,方法返回,我不知道如何将它传输到Akka参与者。 那么,如何从Akka演员中正确使用play WS 2.5.x api呢?

  • 我制作了一个HTML5 iPod。 你可以在这里试试。 http://inventikasolutions.com/demo/iPod 在PC上使用Chrome时。如果我导航到一首歌,它会自动开始播放。但在Android上使用Chrome时,它不会播放这首歌。我必须再次按下播放/暂停按钮才能播放音频。 这是当您选择要播放的歌曲时运行的代码: 这是播放/暂停代码。 它是否与“autoplay”变量有

  • 我正在学习如何为某些曲目创建媒体播放器的教程...每首歌都按我的要求播放然后停止...我想让整个播放列表播放...那是为了在前一个赛道结束后,下一个赛道自动开始... 多谢...