简体   繁体   English

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

[英]Chrome Extension: Record Microphone and Speaker in Background JS

As per latest updates what is proper way to capture microphone and speaker audio for real time audio processing in background js.根据最新更新,在后台 js 中捕获麦克风和扬声器音频以进行实时音频处理的正确方法是什么。 I am stuck at this I have tried all media recorder api,record js api and chrome desktop capture but all of them are returning microphone audio.我被困在这个我已经尝试了所有媒体记录器 api、记录 js api 和 chrome 桌面捕获,但所有这些都返回麦克风音频。 None of them will be able to capture the speaker audio.他们都无法捕获扬声器的音频。 Please suggest a way to implement this scenario请提出一种实现此场景的方法

below is sample code which capture microphone but not speakers:以下是捕获麦克风但不捕获扬声器的示例代码:

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();
}

When you first initiate a call to getUserMedia your available devices will only be audio (meaning microphone) and camera (default webcam).当您第一次向getUserMedia发起呼叫时,您的可用设备将只有音频(即麦克风)和摄像头(默认网络摄像头)。 However, if you call enumerateDevices you will get back a list of all available audio devices.但是,如果您调用enumerateDevices您将获得所有可用音频设备的列表。 You can then specify the specific id of your audio card like so:然后,您可以像这样指定声卡的特定 ID:

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

This takes two calls to getUserMedia with an await in there to get working properly.这需要两次调用 getUserMedia 并在那里等待才能正常工作。 Also, I should note that the devicechange event doesn't fire in Chromium browsers for mediaDevices .另外,我应该注意到devicechange事件不会在 Chromium 浏览器中为mediaDevices That will make it harder to detect configuration changes.这将使检测配置更改变得更加困难。

For a background extension I think you'll have to play around a bit to get this working right.对于后台扩展,我认为您必须稍微尝试一下才能使其正常工作。 You could present the list of devices to the user and let them choose, but that will take some messaging to your front-end script and back again, complicating your setup.您可以向用户展示设备列表并让他们选择,但这会向您的前端脚本发送一些消息并再次返回,从而使您的设置复杂化。

Here is a sample code which lists all available devices.这是一个示例代码,其中列出了所有可用的设备。

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();
  }
  })

}

Let know if this is what you are looking for.让我们知道这是否是您要找的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM