'Puppeteer losing access to the microphone

I am using puppeteer to join a Jitsi meeting from a headless computer. The jitsi bot simply joins the meeting and uses the camera that we have connected to the computer as camera and microphone (with the help of ffmpeg and snd-aloop to route the video to a virtual webcam and the audio to a virtual microphone). The system works most of the time, but sometimes (it seems random), when we try to start the script we notice that there is no audio. After checking the screenshots that puppeteer takes after joining the meeting, we notice that the microphone permission was not granted. Screenshot taken by Puppeteer. Stopping node and restarting the script does not fix it. A reboot of the computer also does not fix this. After a while (sometimes a couple of days later), the problem disappears without us being able to explain why it appeared and disappeared.

I have noticed that when we kill pulseaudio (and we don't restart it before starting the script), we do not have any issue. But then of course we are un-able to select the right microphone as it does not appear in the list of audio devices in Jitsi. This is normal I guess. Then list of microphones that appear here is a list of ALSA devices from the default sound card (Loopback card from snd-aloop). List of microphones when the permission issue is not here.

This tends to point towards an issue in the interaction between puppeteer and pulseaudio, but I am not sure how to check that.

This is our script using puppeteer:

const puppeteer = require('puppeteer');

function delay(time) {
   return new Promise(function(resolve) { 
       setTimeout(resolve, time)
   });
}

(async () => {
  const browser = await puppeteer.launch({
        ignoreDefaultArgs: [
        "--mute-audio",
        ],
        args: [ '--use-fake-ui-for-media-stream',
                '--disable-gpu',
                '--disable-software-rasterizer',
                '--no-sandbox',
                '--ignore-certificate-errors']
    })
  process.on('unhandledRejection', (reason, p) => {
  console.error('Unhandled Rejection at: Promise', p, 'reason:', reason);
  browser.close();
  });
  console.log("Hello, I am the bot")
  const page = await browser.newPage()
  await page.setViewport({ width: 1280, height: 800 })
  console.log("Trying to join")
  await page.goto('https://jitsimeetingaddress, {
                    waitUntil: 'load',
                    timeout: 0});
  const title = await page.title()
  await delay(500);
  console.log("Joining website:")
  console.log(title)
  await delay(500);
  await page.screenshot({ path: 'screen_0_page.png', fullPage: true })
  [...][More navigating and taking screenshots here][...]
  //await browser.close()
})()

One of the first thing we checked are the owners and groups of the audio devices in /dev/snd, but there is no differences in permissions there between the moments when it works and the moments when it doesn't.

Attached is the beginning of a log from my puppeteer bot, in case this provides any help. I had to cut if shortly after the RTC issue is indicated, to keep the post short enough.

Hello, I am the bot
Trying to join
200 [Jisti Meeting address]
WAR Error with Permissions-Policy header: Unrecognized feature: 'interest-cohort'.
200 [Jisti Meeting address]/css/all.css?v=5415
200 [Jisti Meeting address]/libs/do_external_connect.min.js?v=1
LOG (TIME) index.html loaded:    2426.699999988079
200 [Jisti Meeting address]/libs/lib-jitsi-meet.min.js?v=5415
200 [Jisti Meeting address]/libs/app.bundle.min.js?v=5415
INF 2022-01-24T11:48:01.872Z [modules/browser/BrowserCapabilities.js] <new a>:  This appears to be chrome, ver: 98.0.4758.0
WAR The AudioContext was not allowed to start. It must be resumed (or created) after a user gesture on the page [link to google page]
INF 2022-01-24T11:48:03.902Z [features/base/redux] <Object.persistState>:  redux state persisted. 99914b932bd37a50b983c5e7c90ae93b -> 0aaf198eb32c2d4a7bdbd65f37e069fb
INF 2022-01-24T11:48:03.979Z [modules/RTC/RTCUtils.js] <$.init>:  Disable AP: false
DEB 2022-01-24T11:48:03.981Z [modules/connectivity/NetworkInfo.js] <a.updateNetworkInfo>:  updateNetworkInfo JSHandle@object
WAR 2022-01-24T11:48:03.986Z [modules/statistics/AnalyticsAdapter.js] <Object.dispose>:  Disposing of analytics adapter.
INF 2022-01-24T11:48:03.986Z [features/analytics] Initialized 0 analytics handlers
LOG 2022-01-24T11:48:03.988Z [features/base/media] Start muted:
LOG 2022-01-24T11:48:03.993Z [features/base/media] Start audio only set to false
DEB 2022-01-24T11:48:04.165Z [features/base/devices] setAudioOutputDevice: undefined[default]
LOG 2022-01-24T11:48:04.179Z [index.web] <HTMLDocument.<anonymous>>:  (TIME) document ready:     6122.199999988079
INF 2022-01-24T11:48:04.225Z [modules/RTC/RTCUtils.js] list of media devices has changed: JSHandle@array
DEB 2022-01-24T11:48:04.226Z [modules/RTC/RTCUtils.js] Available devices:  JSHandle@array
LOG 2022-01-24T11:48:04.260Z [modules/RTC/RTCUtils.js] Audio output device set to default
DEB 2022-01-24T11:48:04.281Z [features/base/devices] Device list updated:
audioInput:
                [default]
                gopro-mic[42335a21645366fec9d0eff29846a20c25efcffa0cc2602df9564cc1f83d0f1f]
                Loopback Analogue Stereo[dbea40ebbc6eed24fc4382db094b7d49513ba50b5b75fb091f66b551521fd2e9]
audioOutput:
                [default]
                332a Analogue Stereo[86161c040ee99219feab438a7220e8916f3190d770a00498dbdbf77ebdc2b433]
                Loopback Analogue Stereo[80230fc3a105e47d1af716b3a3e562e2b9d8af55db4756aadd98e4feb9d15eec]
videoInput:
                Dummy video device (0x0000)[3b8058da56af28a013471de8735cb88160cab72ea6d0a40313f17893a5f0ab6e]
INF 2022-01-24T11:48:04.296Z [modules/xmpp/xmpp.js] <P._initStrophePlugins>:  P2P STUN servers:  JSHandle@array
LOG 2022-01-24T11:48:04.306Z [modules/xmpp/xmpp.js] <P.connectionHandler>:  (TIME) Strophe connecting:   6249.399999976158
DEB 2022-01-24T11:48:04.309Z [features/prejoin] Failed to execute pre call test -  JSHandle@error
INF 2022-01-24T11:48:04.312Z [modules/RTC/RTCUtils.js] <$.<anonymous>>:  Got media constraints:  {"video":{"height":{"ideal":720},"width":{"ideal":1280},"facingMode":"user"},"audio":{"autoGainControl":true,"echoCancellation":true,"noiseSuppression":true}}
200 https://icecubes-ws2/libs/olm.wasm
WAR 2022-01-24T11:48:04.338Z [modules/RTC/RTCUtils.js] Failed to get access to local media. NotReadableError: Could not start audio source {"video":{"height":{"ideal":720},"width":{"ideal":1280},"facingMode":"user"},"audio":{"autoGainControl":true,"echoCancellation":true,"noiseSuppression":true}}
ERR 2022-01-24T11:48:04.339Z [features/base/tracks] Failed to create local tracks JSHandle@array JSHandle@error
INF 2022-01-24T11:48:04.340Z [modules/RTC/RTCUtils.js] <$.<anonymous>>:  Got media constraints:  {"video":false,"audio":{"autoGainControl":true,"echoCancellation":true,"noiseSuppression":true}}
WAR 2022-01-24T11:48:04.350Z [modules/RTC/RTCUtils.js] Failed to get access to local media. NotReadableError: Could not start audio source {"video":false,"audio":{"autoGainControl":true,"echoCancellation":true,"noiseSuppression":true}}
ERR 2022-01-24T11:48:04.351Z [features/base/tracks] Failed to create local tracks JSHandle@array JSHandle@error
INF 2022-01-24T11:48:04.352Z [modules/RTC/RTCUtils.js] <$.<anonymous>>:  Got media constraints:  {"video":{"height":{"ideal":720},"width":{"ideal":1280},"facingMode":"user"},"audio":false}
LOG Service worker registered. JSHandle@object

Does anyone have any clue at what could be happening? We're scratching our heads here not knowing where to look at to fix this issue.

Thanks!



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source