I would like to record sound from mic and tab. I tried offscreen, but it will required user permission that offscreen.js can't implement it. So I tried to use popup.js to implement it.
But the sound is wired, sometimes it will have buzzing sound, and sometimes I can't even hear the sound that come from the tab. It seems like new MediaStream([...micStream.getAudioTrack(), ...tabStream.getAudioTrack()]) not work perfectly?
```
// popup.js
const getMicrophoneStream = async () => {
try {
const microphoneStream = await navigator.mediaDevices.getUserMedia({
audio: {
autoGainControl: true,
echoCancellation: true,
noiseSuppression: true,
channelCount: CHANNEL,
deviceId: {
exact: 'default'
},
},
});
setAudioPermission(true)
return microphoneStream
} catch (error) {
console.log(error)
setAudioPermission(false)
}
}
const getTabStream = async () => {
const tabs = await chrome.tabs.query({ active: true })
console.log('tabs', tabs)
const currentTab = tabs
.filter(tab => tab.title !== 'Bronci Recorder Extension')
.filter(tab => tab.audible === true)
console.log('currentTab', currentTab)
if (currentTab.length !== 1) return
const streamId = await chrome.tabCapture.getMediaStreamId({
targetTabId: currentTab[0].id,
})
console.log('tabStreamId', streamId)
try {
return await navigator.mediaDevices.getUserMedia({
audio: {
// @ts-ignore
mandatory: {
chromeMediaSource: 'tab',
chromeMediaSourceId: streamId,
},
},
video: {
// @ts-ignore
mandatory: {
chromeMediaSource: 'tab',
chromeMediaSourceId: streamId,
},
},
})
} catch (error) {
console.log(error)
return null
}
}
const handleRecord = async () => {
const microphoneStream = await getMicrophoneStream()
const tabStream = await getTabStream()
console.log('microphoneStream', microphoneStream)
console.log('tabStream', tabStream)
if (!microphoneStream || !tabStream) return
if (audioContext.current) {
audioContext.current.close()
audioContext.current = null
}
audioContext.current = new AudioContext({ sampleRate: SAMPLE_RATE })
const combinedStream = new MediaStream([
...microphoneStream.getAudioTracks(),
...tabStream.getAudioTracks(),
])
const mediaStreamSource = audioContext.current.createMediaStreamSource(combinedStream)
mediaStreamSource.connect(audioContext.current.destination)
const audio = new Audio()
audio.srcObject = combinedStream
audio.play()
}
```