首页 > 解决方案 > 我在录制的声音缓冲区和存储的声音文件之间有一些区别

问题描述

我正在尝试使用 ACRCloud 音频识别开发音乐识别 Web 应用程序。

我在 React 中有一个客户端,它记录笔记本电脑麦克风中的音乐并将其发送到服务器端:

const sendRecording = async (dispatch, arrayBuffer) => {
  const config = {
    headers: {
      'Content-Type': 'multipart/form-data; boundary=${data._boundary}'
    }
  };

  try {
    var formData: FormData = new FormData();
    formData.append('audio', arrayBuffer);

    const res = await axios.post(
      '/api/recording',
      { test: new Buffer(arrayBuffer) },
      config
    );
  } catch (err) {
    console.log(err);
  }
};

const handleRecorder = dispatch => {
  navigator.mediaDevices.getUserMedia({ audio: true }).then(stream => {
    console.log('entra!!!!');
    const mediaRecorder = new MediaRecorder(stream);
    mediaRecorder.start();

    const audioChunks: any[] = [];
    mediaRecorder.addEventListener('dataavailable', event => {
      audioChunks.push(event.data);
    });

    mediaRecorder.addEventListener('stop', async () => {
      const audioBlob = new Blob(audioChunks);
      let arrayBuffer = await new Response(audioBlob).arrayBuffer();
      sendRecording(dispatch, arrayBuffer);
    });

    setTimeout(() => {
      mediaRecorder.stop();
    }, 13000);
  });
};

这显然对我有用并正确发送缓冲区。我在后端得到这样的东西:

<Buffer 7b 22 61 75 64 69 6f 22 3a 7b 22 74 79 70 65 22 3a 22 42 75 66 66 65 72 22 2c 22 64 61 74 61 22 3a 5b 32 36 2c 36 39 2c 32 32 33 2c 31 36 33 2c 31 35 ... >

Node 后端如下所示:

import express = require('express');
import { identifyAudio } from '../../services/acousticFingerprintService';
import fs = require('fs');
const router = express.Router();
import multer from 'multer';
let processMultipart = multer({ storage: multer.memoryStorage() });
const WavEncoder = require('wav-encoder');

router.post('/', processMultipart.array('audio'), (req, res) => {
  let buffer: Buffer = new Buffer(0);
  req.on('data', data => {
    buffer = Buffer.concat([buffer, data]);
  });

  req.on('end', () => {
    const sound = {
      sampleRate: 44100,
      channelData: [
        new Float32Array(buffer)
      ]
    };

    WavEncoder.encode(sound).then(bufferWav => {
      identifyAudio(bufferWav);
    });

    res.send('Recording sent');
  });
});

export const identifyAudio = bitmap => { ... }音频通过函数发送到ACRCloud识别服务

流程有效,但我总是得到“无结果”响应。我试图发送存储在服务器上的音频。它是模拟真实场景的低质量和噪音的录制音频。

let filename = '../../services/sample.wav';
let bitmap: Buffer = fs.readFileSync(path.resolve(__dirname, filename));

发送该位图,我收到了正确的回复,其中包含艺术家姓名、歌曲...

我曾经这样做identifyAudio(buffer),但我总是得到“无法生成指纹”的响应。我用 wav-encoder 对其进行了编码,得到了“无结果”响应。所以我想我正在发送一个结构良好的音频。

标签: javascriptnode.jsreactjsaudioacrcloud

解决方案


identifyAudio(buffer),缓冲区没有头,所以“不能生成指纹”。您使用 wav-encoder 对其进行编码并获得“无结果”响应。您生成的 WAV 文件可能有问题。所以你可以保存源音频缓冲区和你生成的WAV文件,发送到“support@acrcloud.com”,我会测试一下。


推荐阅读