【问题标题】:How to downsample audio recorded from mic realtime in javascript?如何在javascript中对从麦克风实时录制的音频进行下采样?
【发布时间】:2019-03-19 22:53:54
【问题描述】:

我正在使用以下 javascript 来录制音频并将其发送到 websocket 服务器:

const recordAudio = () =>
    new Promise(async resolve => {

        const constraints = {
            audio: {
                sampleSize: 16,
                channelCount: 1,
                sampleRate: 8000
            },
            video: false
        };

        var mediaRecorder;
        const stream = await navigator.mediaDevices.getUserMedia(constraints);

        var options = {
            audioBitsPerSecond: 128000,
            mimeType: 'audio/webm;codecs=pcm'
        };
        mediaRecorder = new MediaRecorder(stream, options);
        var track = stream.getAudioTracks()[0];
        var constraints2 = track.getConstraints();
        var settings = track.getSettings();


        const audioChunks = [];

        mediaRecorder.addEventListener("dataavailable", event => {
            audioChunks.push(event.data);
            webSocket.send(event.data);
        });

        const start = () => mediaRecorder.start(30);

        const stop = () =>
            new Promise(resolve => {
                mediaRecorder.addEventListener("stop", () => {
                    const audioBlob = new Blob(audioChunks);
                    const audioUrl = URL.createObjectURL(audioBlob);


        const audio = new Audio(audioUrl);
                const play = () => audio.play();
                resolve({
                    audioBlob,
                    audioUrl,
                    play
                });
            });

            mediaRecorder.stop();
        });

    resolve({
        start,
        stop
    });
});

这是用于实时 STT 并且 websocket 服务器拒绝发送任何响应。我通过调试检查 sampleRate 没有更改为 8Khz。经过研究,我发现这是 chrome 和 firefox 上的一个已知错误。我找到了一些其他资源,例如 stackoverflow1IBM_STT,但我不知道如何将其适应我的代码。 上述有用的资源是指缓冲区,但我的代码中只有 mediaStream(stream) 和 event.data(blob)。 我是 javascript 和 Audio Api 的新手,所以如果我做错了什么,请原谅我。

如果这有帮助,我有一个等效的 python 代码将数据从麦克风发送到 websocket 服务器,它可以工作。使用的库 = Pyaudio。代码:

 p = pyaudio.PyAudio()
 stream = p.open(format="pyaudio.paInt16",
                        channels=1,
                        rate= 8000,
                        input=True,
                        frames_per_buffer=10)

 print("* recording, please speak")

 packet_size = int((30/1000)*8000)  # normally 240 packets or 480 bytes

 frames = []

        #while True:
 for i in range(0, 1000):
     packet = stream.read(packet_size)
     ws.send(packet, binary=True)

【问题讨论】:

    标签: javascript audio-recording sample-rate


    【解决方案1】:

    要进行实时下采样,请按以下步骤操作:

    1. 首先使用这个获取流实例:

      const stream = await navigator.mediaDevices.getUserMedia(constraints);
      
    2. 从此流创建媒体流源。

      var input = audioContext.createMediaStreamSource(stream);
      
    3. 创建脚本处理器,以便您可以使用缓冲区。我将创建一个脚本处理器,它一次连续地从流中获取 4096 个样本,具有 1 个输入通道和 1 个输出通道。

      var scriptNode = audioContext.createScriptProcessor(4096, 1, 1);
      
    4. 将您的输入与 scriptNode 连接起来。您可以根据需要将脚本节点连接到目的地。

          input.connect(scriptNode);
          scriptNode.connect(audioContext.destination);
      
    5. 现在 scriptProcessor 中有一个 onaudioprocess 函数,您可以在其中对 4096 个样本进行任何操作。 var downsample 将包含(1/采样率)包数。 floatTo16BitPCM 会将其转换为您需要的格式,因为原始数据是 32 位浮点格式。

         var inputBuffer = audioProcessingEvent.inputBuffer;
          // The output buffer contains the samples that will be modified and played
          var outputBuffer = audioProcessingEvent.outputBuffer;
      
          // Loop through the output channels (in this case there is only one)
          for (var channel = 0; channel < outputBuffer.numberOfChannels; channel++) {
              var inputData = inputBuffer.getChannelData(channel);
              var outputData = outputBuffer.getChannelData(channel);
      
      
      
              var downsampled = downsample(inputData);
              var sixteenBitBuffer = floatTo16BitPCM(downsampled);
            }
      
    6. 您的 SixteenBitBuffer 将包含您需要的数据。

      下采样和floatTo16BitPCM的功能在Watson API的这个链接中解释:IBM Watson Speech to Text Api

    您不需要 MediaRecorder 实例。 Watson API 是开源的,您可以寻找一种更好的简化方法来了解他们如何为自己的用例实现它。您应该能够从他们的代码中挽救重要的功能。

    【讨论】:

    • 注意:截至 2014 年 8 月 29 日发布的 Web Audio API 规范,此功能已被标记为已弃用,并且很快将被 AudioWorklet 取代。我面临着与问题中提到的类似的问题,但不确定如何使用 Audioworklet。如果我成功了会更新。
    猜你喜欢
    • 2022-12-10
    • 1970-01-01
    • 1970-01-01
    • 2023-03-21
    • 1970-01-01
    • 2011-03-31
    • 1970-01-01
    • 2020-03-24
    • 1970-01-01
    相关资源
    最近更新 更多