feat(macos): record system audio from a Core Audio tap with Apple's picker - #740
EtienneLescot wants to merge 1 commit into
Conversation
…icker A take picked in Apple's system picker holds no Screen Recording grant, and ScreenCaptureKit hands such a capture its system audio as silence (measured on macOS 26.5). So #737 dropped system audio unless Screen Recording was granted, which brought back the grant the picker removes. Picked takes now record system audio from a Core Audio process tap instead, under its own, narrower 'System Audio Recording Only' grant. Measured alongside a picker stream on 26.5: real audio, in the same process, with no relaunch and no Screen Recording grant. - SystemAudioTap: a global stereo process tap in a private aggregate device. Its IO cycles become CMSampleBuffers stamped on the host clock (makeAudioSampleBuffer, in OpenScreenCaptureCore with tests), so they take the recorder's existing pause/retime path into AudioTrackMixer. - The tap starts off the take's start path, since the first start blocks on macOS' prompt, and stops accepting audio before the writer is finalised. Takes from the app's own picker keep ScreenCaptureKit audio. - `--request-system-audio` raises the prompt on its own. The HUD's system-audio toggle calls it the first time it is turned on, so the prompt never lands on a take that is already counting down. - The permissions window gets a real 'System audio' row there. Its answer has no public read, so after asking it reads 'requested' and offers the matching System Settings pane (Privacy_AudioCapture), with the section named as macOS names it in each of the 15 locales.
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (29)
💤 Files with no reviewable changes (1)
Included review availability: Your plan provides up to 8 included reviews per hour; 7 remain after this review. 📝 WalkthroughWalkthroughAdds macOS system-audio permission tracking and prompt handling for Apple-picker recordings, then captures picker audio through a Core Audio process tap and sends it to the existing audio mixer. The permissions window and localized help show system-audio states. Recording responses no longer include ChangesSystem Audio Capture
Priority: ➖ Normal Estimated code review effort: 4 (Complex) | ~45 minutes Change: Feature Sequence Diagram(s)sequenceDiagram
participant RecordingPrefs
participant registerIpcHandlers
participant MacPermissions
participant CaptureHelper
participant SystemAudioTap
RecordingPrefs->>registerIpcHandlers: publish enabled preference change
registerIpcHandlers->>MacPermissions: askForSystemAudioOnce()
MacPermissions->>CaptureHelper: launch with --request-system-audio
CaptureHelper->>SystemAudioTap: start tap to request access
Suggested reviewers: Merge Risk: ⚪ Minimal · up to No concrete issue in the supplied evidence blocks merging; complete the usual checks before release. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Full details: Docstring CoverageExplanation Docstring coverage is 35.71% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 42 functions across 13 files. (15 skipped: 15 unsupported.)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@coderabbitai review |
✅ Action performedReview finished.
|
Follows #737. With Apple's system picker, recording no longer needs the Screen Recording grant, except for system audio. This PR removes that last exception.
Why
A take picked in
SCContentSharingPickerholds no Screen Recording grant. ScreenCaptureKit still hands such a capture its system-audio buffers, but fills them with zeros: measured on macOS 26.5, about 158 buffers per 3 s, all silent, while the same measuring code with the grant read peak 0.36. So #737 dropped system audio unless Screen Recording was granted, which brought the grant back for anyone who records system audio.A Core Audio process tap (macOS 14.2+) is gated by a separate, narrower permission, System Audio Recording Only (
NSAudioCaptureUsageDescription, already in our Info.plist). It covers the sound the Mac plays and nothing on screen. Measured alongside a picker video stream on 26.5, with no Screen Recording grant: the prompt reads "“App” would like access to record your system audio.", real audio flows after Allow (peak 0.365, ~94 buffers/s), in the same process, with no relaunch.What changes
Helper
SystemAudioTap: a global stereo process tap in a private aggregate device. Each IO cycle becomes aCMSampleBufferstamped on the host clock, the domain ScreenCaptureKit's audio used (makeAudioSampleBuffer, inOpenScreenCaptureCore, with tests). It therefore goes through the recorder's existing pause and retime path intoAudioTrackMixer, which already resamples and reads non-interleaved float.--request-system-audioraises the prompt on its own and exits once it is answered.Electron
Permissions window
Privacy_AudioCapture).Verified
swift build,swift test(48, including the new buffer tests),tsc(app and tests),biome,i18n-check,vitestfull suite (3181 passed)Known limits
excludesCurrentProcessAudioonly ever excluded the helper, which plays nothing.Summary by CodeRabbit