Created
August 9, 2026 16:47
-
-
Save anildigital/9a195654a687524fb544db62894466fe to your computer and use it in GitHub Desktop.
Repro: audio: 'loopbackWithMute' via custom setDisplayMediaRequestHandler never captures data on macOS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html> | |
| <head> | |
| <meta charset="utf-8" /> | |
| <title>loopbackWithMute repro</title> | |
| </head> | |
| <body> | |
| <h3>audio: 'loopbackWithMute' via custom setDisplayMediaRequestHandler picker</h3> | |
| <pre id="log" style="white-space: pre-wrap; font-family: monospace;"></pre> | |
| <script src="renderer.js"></script> | |
| </body> | |
| </html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const { app, BrowserWindow, session, desktopCapturer } = require('electron') | |
| function createWindow () { | |
| const win = new BrowserWindow({ | |
| width: 900, | |
| height: 600, | |
| webPreferences: { | |
| preload: __dirname + '/preload.js' | |
| } | |
| }) | |
| win.loadFile('index.html') | |
| } | |
| app.whenReady().then(() => { | |
| // Custom picker path: we resolve the source ourselves (simulating an | |
| // app's own branded picker UI) instead of setting `useSystemPicker: true`. | |
| session.defaultSession.setDisplayMediaRequestHandler((request, callback) => { | |
| desktopCapturer.getSources({ types: ['screen'] }).then((sources) => { | |
| callback({ video: sources[0], audio: 'loopbackWithMute' }) | |
| }) | |
| }, { useSystemPicker: false }) | |
| createWindow() | |
| }) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // No preload APIs needed for this repro. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const log = (msg) => { | |
| const el = document.getElementById('log') | |
| el.textContent += msg + '\n' | |
| console.log(msg) | |
| } | |
| navigator.mediaDevices.getDisplayMedia({ video: true, audio: true }).then((stream) => { | |
| log('getDisplayMedia() resolved') | |
| stream.getTracks().forEach((track) => { | |
| log(`track: kind=${track.kind} label="${track.label}" readyState=${track.readyState}`) | |
| track.addEventListener('ended', () => log(`EVENT: ${track.kind} track ended (label="${track.label}")`)) | |
| }) | |
| const audioTrack = stream.getAudioTracks()[0] | |
| if (!audioTrack) { | |
| log('No audio track was returned at all.') | |
| return | |
| } | |
| // Web Audio analyser: proves whether any samples are actually flowing, | |
| // independent of readyState/muted (which can lag or misreport). | |
| const ctx = new AudioContext() | |
| const source = ctx.createMediaStreamSource(new MediaStream([audioTrack])) | |
| const analyser = ctx.createAnalyser() | |
| source.connect(analyser) | |
| const buf = new Float32Array(analyser.fftSize) | |
| setInterval(() => { | |
| analyser.getFloatTimeDomainData(buf) | |
| let maxAbs = 0 | |
| for (let i = 0; i < buf.length; i++) maxAbs = Math.max(maxAbs, Math.abs(buf[i])) | |
| log( | |
| `t+${Math.round(performance.now() / 1000)}s: ` + | |
| `readyState=${audioTrack.readyState} muted=${audioTrack.muted} peakAmplitude=${maxAbs.toFixed(4)}` | |
| ) | |
| }, 1000) | |
| }).catch((err) => { | |
| log('getDisplayMedia() rejected: ' + err) | |
| }) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment