Chrome 扩展:在后台 JS 中录制麦克风和扬声器

Posted

技术标签:

【中文标题】Chrome 扩展:在后台 JS 中录制麦克风和扬声器【英文标题】:Chrome Extension: Record Microphone and Speaker in Background 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();

【问题讨论】:

【参考方案1】:

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

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

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

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

【讨论】:

@Feroz : 看看 repo github.com/muaz-khan/Chrome-Extensions ,作为詹姆斯所说的他正在玩的背景扩展。【参考方案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 通话。

以上是关于Chrome 扩展:在后台 JS 中录制麦克风和扬声器的主要内容,如果未能解决你的问题,请参考以下文章

保存录制的音频 blob [JS]

尝试从屏幕+麦克风录制流时出现“DOMException:因关机而失败”

chrome扩展中popup.html和popup.js之间的函数JavaScript(考虑到来自后台的消息)[重复]

强制其他应用在 iOS 中释放麦克风

三星手机无法录制声音另一个应用程序正在使用麦克风?

我怎样才能摆脱 chrome 或其他浏览器中的录音符号?