Chrome record mic/tab audio, and got wired buzzing

103 views
Skip to first unread message

Po Wen Chen (Mayvis)

unread,
Jan 19, 2024, 10:09:01 PM1/19/24
to Chromium Extensions
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()
  }
```

Oliver Dunk

unread,
Jan 23, 2024, 12:02:23 PM1/23/24
to Po Wen Chen (Mayvis), Chromium Extensions
Hi,

Would opening an extension page and starting a recording to get permission work? You could then immediately stop it and move over to the offscreen document to do the actual recording.

It isn't merged yet but I put an example of how to record both audio and video from an offscreen document here: https://github.com/GoogleChrome/chrome-extensions-samples/commit/9ee3bb917bc2fd21f3b70ff02b36125170dcefb3
Oliver Dunk | DevRel, Chrome Extensions | https://developer.chrome.com/ | London, GB


--
You received this message because you are subscribed to the Google Groups "Chromium Extensions" group.
To unsubscribe from this group and stop receiving emails from it, send an email to chromium-extens...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/chromium-extensions/65d1bdb9-aae0-400b-9fd6-fc0764efb0e7n%40chromium.org.
Reply all
Reply to author
Forward
0 new messages