【问题标题】:Is it possible to get raw values of audio data using MediaRecorder()是否可以使用 MediaRecorder() 获取音频数据的原始值
【发布时间】:2020-04-07 20:42:40
【问题描述】:

我正在使用 MediaRecorder() 和 getUserMedia() 来记录来自浏览器的音频数据。它可以工作,但记录的数据是以 Blob 格式记录的。我想获取原始音频数据(幅度),而不是 Blob。有可能吗?

我的代码如下所示:

  navigator.mediaDevices.getUserMedia({audio: true, video: false}).then(stream => {
    const recorder = new MediaRecorder(stream);
    recorder.ondataavailable = e => {
      console.log(e.data); // output: Blob { size: 8452, type: "audio/ogg; codecs=opus" }
    };
    recorder.start(1000); // send data every 1s
  }).catch(console.error);

【问题讨论】:

    标签: javascript webrtc mediarecorder web-mediarecorder


    【解决方案1】:

    MediaRecorder 对于创建文件很有用;如果你想做音频处理,Web Audio 会是更好的方法。请参阅 this HTML5Rocks tutorial,它展示了如何使用来自 Web Audio 的 createMediaStreamSource 将 getUserMedia 与 Web Audio 集成。

    【讨论】:

      【解决方案2】:

      不需要 MediaRecorder。使用网络音频访问原始数据值,例如like this:

      navigator.mediaDevices.getUserMedia({audio: true})
      .then(spectrum).catch(console.log);
      
      function spectrum(stream) {
        const audioCtx = new AudioContext();
        const analyser = audioCtx.createAnalyser();
        audioCtx.createMediaStreamSource(stream).connect(analyser);
      
        const canvas = div.appendChild(document.createElement("canvas"));
        canvas.width = window.innerWidth - 20;
        canvas.height = window.innerHeight - 20;
        const ctx = canvas.getContext("2d");
        const data = new Uint8Array(canvas.width);
        ctx.strokeStyle = 'rgb(0, 125, 0)';
      
        setInterval(() => {
          ctx.fillStyle = "#a0a0a0";
          ctx.fillRect(0, 0, canvas.width, canvas.height);
      
          analyser.getByteFrequencyData(data);
          ctx.lineWidth = 2;
          let x = 0;
          for (let d of data) {
            const y = canvas.height - (d / 128) * canvas.height / 4;
            const c = Math.floor((x*255)/canvas.width);
            ctx.fillStyle = `rgb(${c},0,${255-x})`;
            ctx.fillRect(x++, y, 2, canvas.height - y)
          }
      
          analyser.getByteTimeDomainData(data);
          ctx.lineWidth = 5;
          ctx.beginPath();
          x = 0;
          for (let d of data) {
            const y = canvas.height - (d / 128) * canvas.height / 2;
            x ? ctx.lineTo(x++, y) : ctx.moveTo(x++, y);
          }
          ctx.stroke();
        }, 1000 * canvas.width / audioCtx.sampleRate);
      };
      

      【讨论】:

        【解决方案3】:

        我用下面的代码实现了一个整数数组进入控制台。至于它们的含义,我认为它们是振幅。

        const mediaRecorder = new MediaRecorder(mediaStream);
        mediaRecorder.ondataavailable = async (blob: BlobEvent) => console.log(await blob.data.arrayBuffer());
        mediaRecorder.start(100);

        如果你想画它们,那么我在 codepen 上找到了这个例子:https://codepen.io/rhwilburn/pen/vYXggbN,一旦你点击它就会使圆圈产生脉冲。

        【讨论】:

        • 不,不是振幅。它们代表由 opus 编解码器编码的 webm 音频文件的字节。这是二进制数据,不是原始信号。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多