【问题标题】:Chrome Extension: Record Microphone and Speaker in Background JSChrome 扩展:在后台 JS 中录制麦克风和扬声器
【发布时间】:2020-03-02 20:39:53
【问题描述】:

根据最新更新,在后台 js 中捕获麦克风和扬声器音频以进行实时音频处理的正确方法是什么。我被困在这我已经尝试了所有媒体记录器 api、记录 js api 和 chrome 桌面捕获,但它们都在返回麦克风音频。他们都无法捕捉到扬声器的音频。请提出一种实现此方案的方法

以下是捕获麦克风但不捕获扬声器的示例代码:

var audioChunks;
startRecord.onclick = e => {
  startRecord.disabled = true;
  stopRecord.disabled=false;
  // This will prompt for permission if not allowed earlier
  navigator.mediaDevices.getUserMedia({audio:true})
    .then(stream => {
      audioChunks = []; 
      rec = new MediaRecorder(stream);
      rec.ondataavailable = e => {
        audioChunks.push(e.data);
        if (rec.state == "inactive"){
          let blob = new Blob(audioChunks,{type:'audio/x-mpeg-3'});
          recordedAudio.src = URL.createObjectURL(blob);
          recordedAudio.controls=true;
          recordedAudio.autoplay=true;
          audioDownload.href = recordedAudio.src;
          audioDownload.download = 'mp3';
          audioDownload.innerHTML = 'download';
       }
      }
    rec.start();  
    })
    .catch(e=>console.log(e));
}
stopRecord.onclick = e => {
  startRecord.disabled = false;
  stopRecord.disabled=true;
  rec.stop();
}

【问题讨论】:

    标签: javascript google-chrome-extension audio-recording


    【解决方案1】:

    当您第一次向getUserMedia 发起呼叫时,您的可用设备将只有音频(即麦克风)和摄像头(默认网络摄像头)。但是,如果您致电enumerateDevices,您将获得所有可用音频设备的列表。然后,您可以像这样指定声卡的特定 ID:

    navigator.mediaDevices.getUserMedia({audio:{deviceId:{exact: deviceId}}})
    

    这需要两次调用 getUserMedia 并在那里等待才能正常工作。另外,我应该注意devicechange 事件在mediaDevices 的Chromium 浏览器中不会触发。这将使检测配置更改变得更加困难。

    对于后台扩展,我认为您必须尝试一下才能使其正常工作。您可以将设备列表呈现给用户并让他们选择,但这会向您的前端脚本发送一些消息并再次返回,从而使您的设置变得复杂。

    【讨论】:

    【解决方案2】:

    这是一个列出所有可用设备的示例代码。

    navigator.mediaDevices.enumerateDevices()
    .then((devicesInfo)) => {
    // Expect devices of kind `audioinput`, `audiooutput`, `videoinput` and other media cards available.
    // Internal default speakers would fall under `audiooutput` and internal default microphone would fall under `audioinput`.
    const select = document.createElement('select');
    devicesInfo.forEach((device, index) => {
        const option = document.createElement('option');
        option.value = deviceInfo.deviceId;
    
        if(deviceInfo.kind === 'audioinput')
          option.text = deviceInfo.label;
    
        select.appendChild(option);
    })
    document.body.appendChild(select);
    
    ...
    // Let user make the selection of device. Once selected, start the recording.
    ...
    
    // select.value has the selected deviceId. Use `onChange` event of select to capture the value.
    const constraints = {
        audio: {deviceId: select.value ? {exact: select.value} : undefined}
      };
      
      var audioChunks = [];
      navigator.mediaDevices.getUserMedia(constraints)
      .then((stream) => {
          window.stream = stream; // make stream available to console
      
          var rec = new MediaRecorder(stream);
          rec.ondataavailable = (e) => {
              audioChunks.push(e.data);
              if (rec.state == "inactive"){
                  let blob = new Blob(audioChunks,{type:'audio/x-mpeg-3'});
                  const recording = document.createElement('audio');
                  recording.id = "recording";
                  recording.src = URL.createObjectURL(blob);
                  recording.controls=true;
                  recording.autoplay=true;
                  document.body.removeChild(document.getElementById('recording'));
                  document.body.appendChild(downloadLink);
    
                  const downloadLink = document.createElement('a');
                  downloadLink.id = "downloadLink";
                  downloadLink.href = recordedAudio.src;
                  downloadLink.download = 'mp3';
                  downloadLink.innerHTML = 'download';
                  document.body.removeChild(document.getElementById('downloadLink'));
                  document.body.appendChild(downloadLink);
        };
    
        // Start recording whenever user prefers to start.
        rec.start();
    
        ...
        ...
    
    
        // Stop recording whenever user prefers to stop.
        rec.stop();
      }
      })
    
    }
    

    如果这是您要找的,请告诉我们。

    【讨论】:

    • 灵感来自这个小提琴 - jsfiddle.net/bomzj/beap6n2g 并根据相关需求进行了修改。我添加了 1. enumerateDevices 调用以列出所有可能的设备。 2.constraintsnavigator.mediaDevices.getUserMedia 通话。
    猜你喜欢
    • 2014-08-11
    • 1970-01-01
    • 2011-11-21
    • 2021-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多