electron: Desktop audio capture does not work on Mac and Linux
- Electron version: 1.6.2, 1.6.5, 1.7.6, 2.0.2, 3.x, 4.0.5
- Operating system: Mac OS X Sierra, Linux (Debian Jessie)
Expected behavior
Given the defined DesktopCapture API for capturing both audio and video for the entire desktop, we should get a working audio stream on Windows, Linux and Mac.
Actual behaviour
Electron version 4.0.5: On Mac and Linux, the error callback triggers with the respective messages:
getUserMediaError: DOMException: Could not start audio source // Mac
Failed to query stereo recording // Linux
Electron Version 1.7.6: On Mac and Linux, the error callback triggers with the error:
NavigatorUserMediaError
constraintName: ""
message: ""
name: "TrackStartError"
Electron Version 1.6.2 and 1.6.5: On Mac and Linux, the video stream is received successfully, albeit, with no audio.
Below are the constraints defined as per the DesktopCapture API:
const constraints = {
audio: {
mandatory: {
chromeMediaSource: 'desktop'
}
},
video: {
mandatory: {
chromeMediaSource: 'desktop'
}
}
}
Please note: on Windows, the audio capture works correctly.
How to reproduce
git clone https://github.com/mhashmi/electron-desktop-capture
cd electron-desktop-capture
npm install
npm start
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Reactions: 49
- Comments: 83 (8 by maintainers)
Commits related to this issue
- docs: note desktop audio limitation on macOS (#17738) Closes #10515. Notes fundamental limitation in `navigator.mediaDevices.getUserMedia` for audio capture on some platforms so that users are aware ... — committed to electron/electron by codebytere 5 years ago
- docs: note desktop audio limitation on macOS (#17738) Closes #10515. Notes fundamental limitation in `navigator.mediaDevices.getUserMedia` for audio capture on some platforms so that users are aware ... — committed to kiku-jw/electron by codebytere 5 years ago
@jasonrudolph Please use GH reactions instead of adding a “+1” comment.
GH reaction == GitHub reaction, you used one just now to thumbs down my comment asking you to use them 🤔
@MarshallOfSound @codebytere +1 for reopening this issue. It’s extremely frustrating that the MacOS side of this issue came to a resolution, but the Linux side has remained unanswered for over 3 years despite there still being a problem and no functional limitation on the Linux side, unlike on MacOS.
This issue is still occurring on Linux, pls reopen
Please reopen this issue.
Can reproduce on
Electron/9.1.2
andElectron/10.0.0-beta.15
on GNU/LinuxBringing this up as per
and the fact that this is totally possible with pulseaudio on GNU/Linux unlike the mac thing mentioned above.
I was searching through the Chromium issue tracker, and found this: https://bugs.chromium.org/p/chromium/issues/detail?id=1143761&q=linux streaming&can=2
This may be worth keeping an eye on, since it seems related to this issue. It’s possible that this issue may see resolution when the Chromium team starts pushing fixes.
I think the issue stems from the fact upstream chromium doesn’t support this on linux. I think this maybe the wrong place to be asking for this
@codebytere I believe that this issue needs to be reopened
so, since this is not being reopened, is making a new issue a good idea? idk how these stuff works here
Looking into this today; it seems to DCHECK on master now. I’ll try to see how far i get on this and let y’all know.
I just tested this on electron 4.0.0 and still doesn’t work. The error I get is “NotReadableError: Could not start audio source”
Is there a good workaround at least?
I’ve recently had this issue on Mac, though I’m a little bit late in the comments, I have to say I bypassed it using Sound flower. Here is a detailed blog post about my solution: This include every code snippet to record system audio on MacOS and even video and then combine both streams to make audio and video together.
@MarshallOfSound: As someone that got a notification from you for a thread I’m not even participating in, is it helpful for me to say, “Please make sure you’re @mentioning the right person.”??? 😜
On the Linux side, if using PulseAudio to pull from the monitor of the default sink is unacceptable when capturing specific apps rather than the whole desktop, you could register a virtual sink and let the end-user manage the routing. Or taking it one step further, register the virtual sink and load module-combine-sink to merge the default sink with the virtual sink. This is likely what the end-user would be doing anyway, so all the they would have to do is temporarily change the app’s output sink to the one created by the module.
Personally, if going with the “always pull from the monitor” approach, I’d instead use module-loopback with a virtual sink to do the routing. This way if the end-user has some strange audio setup, they can manually re-route (through their own module-loopback or module-combine-sink or whatever) where they wouldn’t be so easily able to if Electron pulls directly from the monitor.
There are many ways this could be implemented on Linux through PulseAudio. People on different audio backends (such as ALSA, or JACK) would still be out of luck, but I’m pretty sure the vast majority of people are using PulseAudio these days.
I ended up spending a decent chunk of time trying to figure this out. This is a limitation put in place by Mac Os X on a system level. Any apps that want to access the system’s audio require a signed kernel. From my understanding, this is something that chromium does not provide.
A little more on the topic here: https://stackoverflow.com/questions/18443621/mac-os-x-virtual-audio-driver
The only workaround I have found is to use SoundFlower to capture system audio and pass it through a virtual audio input device, which is accessible via getUserMedia().
I have this same problem currently, I found the error on Linux and on Mac OS, pls reopen it
I can confirm issue persists on 2.0.11 and 3.0
I’d like to see your solution, I have the same problem, but don’t have an experience with Linux to understand how to use PulsAudio.
+1 , I also believe that this should be reopened as the Linux side of the issue was ignored when it was closed. Pulseaudio is capable of this , if this is fixed many apps using electron will also be able to use this.
Hi @codebytere. The issue exists in Electron 2.0.2 as well (please see the issue description above and the
Electron versions
line for all versions I tested against). Additionally, the repository replicating the issue targets electron 2.0.2.Note: I’ll find some time to test this again on Electron 2.0.10 as well as Electron 3.x over this week and post an update accordingly.
I’m assuming since the above issue (Chromium bug) is still open that Linux audio capture is still not implemented for Electrons apps?
Just gently pinging this as we are now in February 😄
here’s what i use to reproduce this issue https://github.com/Kyuunex/electron-screen-capture-test i forked and modified from someone’s tutorial idk if i’m doing it right or wrong but it works on Windows and not on Linux, so…
same issue
Arrgh, I had headphones in my mac and they were lying next to the microphone, which resulted in me thinking the capture was coming through correctly.
Thank you for pointing it out, and apologies from my end.
sure, what I did is:
I used spawn to run the commands as follow:
Step 1:
const monitorProcess = spawn(‘pacmd list-sources | grep -B 1 analog-stereo.monitor | grep name:’, { shell: true });
this actually checks if there is already a monitor or not (simple way we need to create this monitor if its not present, there is one default monitor but its of no use, so to route the system audio we need to create this, I’ll reference it as user monitor hence forth to explain other steps"
Step 2:
monitorProcess.stdout.on(‘data’, function (data) { const output = data.toString(); const l = output.split(‘\n’) if(l.length <= 2){ const regex = /name:\s*<(.+)>/i; const match = output.match(regex); let monitorName if (match && match.length > 1) { monitorName = match[1]; } const moduleGenerate = spawn(
pactl load-module module-remap-source master=${monitorName} source_properties=device.description=Computer-sound
, { shell:true }) moduleGenerate.stdout.on(‘end’, ()=>{ }) } });This simply checks the if the user monitor already created (monitors refresh/reset after a system restart, if its already present then no need to create it). (to get more idea about this simply run the commands in step1 followed by step2 and find it your self, do it for 5-6 times and you will be comfortable with what we are doing)
Step 3:
Once the monitor is created, we can use this in the frontend (webRTC call) and it will be listed as one of the sources. This source will acts a way to get the system audio.
Step 4:
Once this is done, you can take the microphone audio source as well (two webRTC calls) then you’ll have to combine these two sources (if you need help regarding this I would be happy to help, this too can be done with vanilla javascript without any packages)
I also had the problem in Ubuntu (video with audio stream of a BrowserWindow) and solved it in our app with the help of “paclient” (https://github.com/mscdex/paclient).
Then the corresponding deviceId can be used in the audio constraints and mixed with the video stream to get a video-with-audio stream. But a simpler solution would of course be better.
im facing the same issue right now 😦 pls reopen it
@MarshallOfSound @codebytere would you mind reopening this is issue as on Linux at least there has been a regression which has resulted in audio capture on Linux not working.
Haha, sorry Jason. Been doing this from my phone and didn’t check the at mention, my bad 😸