【问题标题】:Detect silence in audio recording检测录音中的静音
【发布时间】:2022-02-26 11:38:11
【问题描述】:

JavaiOS 也有类似的问题,但我想知道通过 getUserMedia() 在 javascript 中检测音频记录的静音。所以给定:

navigator.mediaDevices.getUserMedia({ audio: true })
  .then(stream => {
    const mediaRecorder = new MediaRecorder(stream);
    mediaRecorder.start();

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

    mediaRecorder.addEventListener("stop", () => {
      const audioBlob = new Blob(audioChunks);
      const audioUrl = URL.createObjectURL(audioBlob);
      const audio = new Audio(audioUrl);
      audio.play();
    });
  });

我想知道是否可以在stop 事件中的BlobURLAudio 对象上检查是否存在不存在音频。如果选择了坏的麦克风或虚拟设备 - 任何类似的东西。我之前检查了 blob 的大小,但无声音频仍然有文件大小。我可以通过ffmpeg 在后端执行此操作,但希望在纯 JS 中有一种方法可以简化。

【问题讨论】:

  • 每次dataavailable 事件执行此操作可能会很昂贵,但也许尝试将 Blob 转换为 AudioBuffer 并读取通道值?如果它们都为零(或接近于零),您可以假设没有检测到音频。在此处将 Blob 转换为 AudioBuffer:stackoverflow.com/a/61531985/5522641
  • 我认为您可以使用Kaiido 建议的此代码:stackoverflow.com/a/46781986/11966136

标签: javascript audio


【解决方案1】:

借助受Visualizations with Web Audio API 启发的解决方案,您可以设置所需的最低分贝并检测是否记录了任何内容。

const MIN_DECIBELS = -45;

navigator.mediaDevices.getUserMedia({ audio: true })
  .then(stream => {
    const mediaRecorder = new MediaRecorder(stream);
    mediaRecorder.start();

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

    const audioContext = new AudioContext();
    const audioStreamSource = audioContext.createMediaStreamSource(stream);
    const analyser = audioContext.createAnalyser();
    analyser.minDecibels = MIN_DECIBELS;
    audioStreamSource.connect(analyser);

    const bufferLength = analyser.frequencyBinCount;
    const domainData = new Uint8Array(bufferLength);

    let soundDetected = false;

    const detectSound = () => {
      if (soundDetected) {
        return
      }

      analyser.getByteFrequencyData(domainData); 

      for (let i = 0; i < bufferLength; i++) {
        const value = domainData[i];

        if (domainData[i] > 0) {
          soundDetected = true
        }
      }

      window.requestAnimationFrame(detectSound);
    };

    window.requestAnimationFrame(detectSound);

    mediaRecorder.addEventListener("stop", () => {
      const audioBlob = new Blob(audioChunks);
      const audioUrl = URL.createObjectURL(audioBlob);
      const audio = new Audio(audioUrl);
      audio.play();
      
      console.log({ soundDetected });
    });
  });

【讨论】:

  • 太棒了。我有两个后续问题要问您: 1. 您介意解释使用 -45dB 作为阈值的基本原理吗? 2. 我很好奇如何调整它以仅分析第一块数据(例如,10-15 秒)。我正在使用它来检测错误选择的输入,所以我想尽快通知用户,第一批数据就足够了。
  • 1.老实说,-45 是最适合我忽略白噪声和背景声音的值。 2.我相信js目前没有办法对音频进行切片或选择n秒。但您可以设置超时时间,10 秒后停止录制,然后开始新的录制。
猜你喜欢
  • 2011-08-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-31
  • 2021-02-06
  • 2019-07-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多