docs: improve desktop-capturer loopback docs by alectrocute · Pull Request #47493 · electron/electron · GitHub | Latest TMZ Celebrity News & Gossip | Watch TMZ Live
Skip to content

docs: improve desktop-capturer loopback docs #47493

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

alectrocute
Copy link

Description of Change

Checklist

Release Notes

Notes: none

Copy link

welcome bot commented Jun 18, 2025

💖 Thanks for opening this pull request! 💖

Semantic PR titles

We use semantic commit messages to streamline the release process. Before your pull request can be merged, you should update your pull request title to start with a semantic prefix.

Examples of commit messages with semantic prefixes:

  • fix: don't overwrite prevent_default if default wasn't prevented
  • feat: add app.isPackaged() method
  • docs: app.isDefaultProtocolClient is now available on Linux

Commit signing

This repo enforces commit signatures for all incoming PRs.
To sign your commits, see GitHub's documentation on Telling Git about your signing key.

PR tips

Things that will help get your PR across the finish line:

  • Follow the JavaScript, C++, and Python coding style.
  • Run npm run lint locally to catch formatting errors earlier.
  • Document any user-facing changes you've made following the documentation styleguide.
  • Include tests when adding/changing behavior.
  • Include screenshots and animated GIFs whenever possible.

We get a lot of pull requests on this repo, so please be patient and we will get back to you as soon as we can.

Copy link
Member

@nikwen nikwen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you so much for the docs change! Appreciate that a lot!

I'll take a closer look when I'm at a computer.

Could you please wrap lines between 80 and 100 characters as per our docs style guide?

@@ -62,7 +62,7 @@ stopButton.addEventListener('click', () => {
<body>
<button id="startButton" class="button">Start</button>
<button id="stopButton" class="button">Stop</button>
<video width="320" height="240" autoplay></video>
<video width="320" height="240" autoplay controls></video>
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DX improvement: controls being visible is important for the dev to be able to easily determine if there's an audio track available or not.

@alectrocute
Copy link
Author

Thanks so much @nikwen! I took your feedback and ran with it, rewrote a bunch of stuff and added even more clarity. Let me know what you think!

@alectrocute alectrocute requested a review from nikwen June 18, 2025 01:10
Copy link
Member

@nikwen nikwen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! This is great.

Also requesting a review from @codebytere as she probably has the best understanding of that code.

@nikwen nikwen requested a review from codebytere June 18, 2025 15:40
@alectrocute
Copy link
Author

Thanks so much, @nikwen. I've applied your feedback.

Last thing I'm debating is adding a "macOS Caveats" header to lead the "System Audio Capture" sections at the bottom. I kinda feel like the macOS notes at the bottom come out of nowhere. Thoughts?

@nikwen
Copy link
Member

nikwen commented Jun 18, 2025

Last thing I'm debating is adding a "macOS Caveats" header to lead the "System Audio Capture" sections at the bottom. I kinda feel like the macOS notes at the bottom come out of nowhere. Thoughts?

I think that's a great idea. Thanks!

@alectrocute
Copy link
Author

Last thing I'm debating is adding a "macOS Caveats" header to lead the "System Audio Capture" sections at the bottom. I kinda feel like the macOS notes at the bottom come out of nowhere. Thoughts?

I think that's a great idea. Thanks!

Done—Looks much better now.

@electron-cation electron-cation bot removed the new-pr 🌱 PR opened recently label Jun 19, 2025
@alectrocute alectrocute requested a review from nikwen June 19, 2025 17:38
Copy link
Member

@nikwen nikwen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you so much!

I found some more comments on other ways to make loopback audio capture work on macOS 14.2+:

https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/flag_descriptions.cc;l=6247-6253;drc=19d14ae4a957ef0f158e3b37cc7f3c76e839ce5d

https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/flag_descriptions.cc;l=6235-6238;drc=19d14ae4a957ef0f158e3b37cc7f3c76e839ce5d

I wonder if that would work around the macOS 15 bugs. (Or does it introduce new ones?)

Also added some minor things inline. This PR is in pretty good shape now in my opinion.


### System Audio Capture (before macOS 12.3)

On macOS 12.3 or lower, system audio capture is not supported due to a fundamental limitation whereby
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
On macOS 12.3 or lower, system audio capture is not supported due to a fundamental limitation whereby
Before macOS 12.3, system audio capture is not supported due to a fundamental limitation whereby

Sounds like it works on 12.3.

Copy link

@shirakaba shirakaba Jun 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can indeed try opting in to it by enabling the MacSckSystemAudioLoopbackOverride flag, but one downstream codepath regards ScreenCaptureKit as too buggy to use until 13.2, so I'm not sure it'll work in practice.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I was playing it safe here. We can and probably should get more specific.

### System Audio Capture (before macOS 12.3)

On macOS 12.3 or lower, system audio capture is not supported due to a fundamental limitation whereby
apps that want to access the system's audio require a [signed kernel extension](https://developer.apple.com/library/archive/documentation/Security/ConceptualSystem_Integrity_Protection_Guide/KernelExtensions/KernelExtensions.html).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
apps that want to access the system's audio require a [signed kernel extension](https://developer.apple.com/library/archive/documentation/Security/ConceptualSystem_Integrity_Protection_Guide/KernelExtensions/KernelExtensions.html).
apps that want to access the system's audio require a
[signed kernel extension](https://developer.apple.com/library/archive/documentation/Security/ConceptualSystem_Integrity_Protection_Guide/KernelExtensions/KernelExtensions.html).

Wrapping between 80 and 100 chars.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess I'm a total markdown noob but how do I wrap a long URL link without breaking it? Whenever I try to split that big string, it breaks the link in my Markdown Preview.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, links can't be wrapped. It's okay if links are longer if they are the only thing in a line.

> ```js
> // main.js
> app.commandLine.appendSwitch('enable-features', 'MacSckSystemAudioLoopbackOverride');
> ```
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can indeed try opting in to it by enabling the MacSckSystemAudioLoopbackOverride flag, but one downstream codepath regards ScreenCaptureKit as too buggy to use until 13.2, so I'm not sure it'll work in practice.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I honestly just need to test this on macOS 12.x to get to the bottom of it. I was erring on the side of caution here.

Copy link

@shirakaba shirakaba left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do think the desktopCapturer docs need some clarifying for macOS. They have led me (and, judging by weekly threads on Reddit, many others) astray. These changes help a lot, thanks!


It is possible to circumvent this limitation by capturing system audio with another macOS app like Soundflower and passing it through a virtual audio input device. This virtual device can then be queried with `navigator.mediaDevices.getUserMedia`.
On macOS 12.3+, `navigator.mediaDevices.getDisplayMedia` can be used to capture system audio

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be good to be explicit about which macOS versions, if any, navigator.mediaDevices.getUserMedia() can be used on.

I seem to recall from recent testing on macOS 14.6.1 that it can't be used at all, but worth double-checking before reporting it in the docs.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm unaware of this. 😅

Comment on lines +111 to +118
> [!NOTE]
> Due to ongoing changes in Chromium, capturing system audio is experimental on macOS 15+ and requires the
> following [command line switch](./command-line-switches.md) to be appended. Please note that you may experience bugs.
>
> ```js
> // main.js
> app.commandLine.appendSwitch('enable-features', 'MacSckSystemAudioLoopbackOverride');
> ```
Copy link

@shirakaba shirakaba Jun 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is inaccurate.

Looking at how IsSystemLoopbackCaptureSupported() is implemented in Chromium, loopback capture depends on both the macOS version and the state of the MacSckSystemAudioLoopbackOverride and MacCatapSystemAudioLoopbackCapture flags (which are both disabled by default). The audio system used may be based on ScreenCaptureKit or Core Audio taps.

  • 🔴 version < 12.3:
    • Loopback capture is not possible.
  • 🔴 12.3 ≤ version < 13.0:
    • Loopback capture is probably not possible. Although ScreenCaptureKit is technically available from macOS 12.3, the Chromium codebase notes that it is too buggy to activate until 13.2. You can try enabling the MacSckSystemAudioLoopbackOverride flag to opt in to it, but I think it won't work in practice.
  • 🔴 13.0 ≤ version < 13.2:
    • Loopback capture is probably not possible. Although the top-level IsMacSckSystemAudioLoopbackCaptureEnabled() check defaults to true for this version range (meaning that the ScreenCaptureKit implementation is enabled even without enabling the MacSckSystemAudioLoopbackOverride flag), in practice, certain downstream codepaths treat it as too buggy to activate.
  • 🟢 13.2 ≤ version < 14.2:
    • Loopback capture is possible, via ScreenCaptureKit only, and is enabled by default; no flag needed.
  • 🟢 14.2 ≤ version < 15.0:
    • Loopback capture is possible, via either ScreenCaptureKit or Core Audio taps. By default, it is enabled, and done via ScreenCaptureKit. However, you can opt-in to Core Audio taps instead by enabling the MacCatapSystemAudioLoopbackCapture flag (which takes precedence).
  • 🟡 15.0 ≤ version:
    • Loopback capture is possible, via either ScreenCaptureKit or Core Audio taps. By default, it is disabled altogether.
      • To enable it via Core Audio taps (the preferred approach from macOS 15.0 and above), enable the MacCatapSystemAudioLoopbackCapture flag. As this flag takes precedence, it doesn't matter whether MacSckSystemAudioLoopbackOverride is enabled or disabled.
      • To enable it via ScreenCaptureKit (not recommended, due to permissions prompt issues from macOS 15.0), you must enable the MacSckSystemAudioLoopbackOverride flag and disable/omit the MacCatapSystemAudioLoopbackCapture flag.

So, in summary, to support the maximum version range of 13.2 ≤ version, you should enable the MacCatapSystemAudioLoopbackCapture flag to extend support for version ≥ 15.0.

If both the MacSckSystemAudioLoopbackOverride and MacCatapSystemAudioLoopbackCapture flags are enabled, the latter will take precedence.

I should clarify that this is just based on my analysis of the latest commit on the main branch of Chromium. It might be that things were different in previous versions of Chromium, and it might be that Electron builds Chromium with different flags (however, I find no search results for either).

Does this match your experience?

Copy link
Author

@alectrocute alectrocute Jun 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a great write-up, thank you. I see that there's definitely some inaccuracies that'll need to be fixed here.

Per my experience, talking strictly system audio capture (there very well could be horrible bugs related to screen capture but I haven't really tested that) — For macOS versions 13.2 through 15.5, I'm able to verify that system audio capture works great via ScreenCaptureKit, only flags that are needed are MacSckSystemAudioLoopbackOverride. System permission prompts work fine.

For testing, I've created this little NPM package to make things easy in Electron Fiddle or an example project of your choice: https://github.com/alectrocute/electron-audio-loopback/tree/main

The implementation in my package is all I've tested, so we'll want to definitely reinforce in the docs that a lot of this is still experimental.

Copy link

@shirakaba shirakaba Jun 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In order to provide complete guidance, the biggest questions in my mind are:

  • For 12.3 ≤ version < 13.0:
    • if you enable MacSckSystemAudioLoopbackOverride, does loopback capture work?
  • For 13.0 ≤ version < 13.2:
    • without passing any flags, does loopback capture work at all?
  • For 15.0 ≤ version:
    • without passing any flags, does loopback capture work at all?
    • if you enable MacCatapSystemAudioLoopbackCapture, does loopback capture work?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • For 12.3 ≤ version < 13.0:

I will report back.

  • For 13.0 ≤ version < 13.2:

I will report back.

  • For 15.0 ≤ version:

    • without passing any flags, does loopback capture work at all?

I can verify that without passing any flags, loopback capture does not work. No errors thrown, the getDisplayMedia audio media track just arrives in an ended state.

  • if you pass MacCatapSystemAudioLoopbackCapture , does loopback capture work?

I will report back.

@shirakaba
Copy link

shirakaba commented Jun 20, 2025

I found some more comments on other ways to make loopback audio capture work on macOS 14.2+:

https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/flag_descriptions.cc;l=6247-6253;drc=19d14ae4a957ef0f158e3b37cc7f3c76e839ce5d

https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/flag_descriptions.cc;l=6235-6238;drc=19d14ae4a957ef0f158e3b37cc7f3c76e839ce5d

@nikwen I looked into these when doing my analysis in this comment. I think the flag descriptions are unhelpful, as they don't reflect the full behaviour as to how they're treated in the source (e.g. how 12.3 ≤ version < 13.0 and version ≥ 15.0 are handled) and how they interact with each other.

@nikwen
Copy link
Member

nikwen commented Jul 1, 2025

Thanks, @shirakaba and @alectrocute, for diving further into this. Can you ping me (@nikwen) when you've figured out how it all works and have updated the PR? I'll be honest: I've never worked with system audio capture in Electron.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation 📓 semver/patch backwards-compatible bug fixes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

desktopCapturer: Use ScreenCaptureKit API to enable capturing loopback audio on macOS
3 participants

TMZ Celebrity News – Breaking Stories, Videos & Gossip

Looking for the latest TMZ celebrity news? You've come to the right place. From shocking Hollywood scandals to exclusive videos, TMZ delivers it all in real time.

Whether it’s a red carpet slip-up, a viral paparazzi moment, or a legal drama involving your favorite stars, TMZ news is always first to break the story. Stay in the loop with daily updates, insider tips, and jaw-dropping photos.

🎥 Watch TMZ Live

TMZ Live brings you daily celebrity news and interviews straight from the TMZ newsroom. Don’t miss a beat—watch now and see what’s trending in Hollywood.