fix(mac): honor selected microphone in native ScreenCaptureKit capture#663
fix(mac): honor selected microphone in native ScreenCaptureKit capture#663rayl15 wants to merge 3 commits into
Conversation
getConnectedRegionTransition and its only-local helpers (easeConnectedPan, getLinearFocus, lerp) were unreferenced, leaving the cubicBezier import unused too. tsc --noUnusedLocals failed the build. Drop the dead cluster.
The native recorder received the web MediaDevices deviceId (an opaque per-origin hash) and the web label, then tried to match them against AVCaptureDevice uniqueID/localizedName. The hashed id never matches a Core Audio uniqueID and the web label rarely equals localizedName verbatim, so resolution returned nil and ScreenCaptureKit silently recorded the system default mic regardless of the user's selection. - Add a `--list-microphones` mode to the helper that emits the real Core Audio input devices (uniqueID + localizedName) as JSON. - Add a list-native-microphones IPC + preload binding. - At native-start, map the selected mic to its real uniqueID via that enumeration and pass it as microphoneDeviceId so SCK records the chosen device. - Make the Swift resolver prefer the uniqueID and fall back to tolerant (case-insensitive / containment) label matching.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughAdds macOS native microphone enumeration (typings, preload bridge, IPC handler, Swift CLI) and integrates resolved device IDs into native screen recording startup. Separately, removes connected zoom/pan interpolation helpers and stops producing zoom transition objects. ChangesNative Microphone Enumeration and Selection
Zoom Transition Cleanup
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 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 |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/hooks/useScreenRecorder.ts`:
- Around line 1456-1487: The native macOS recorder must never receive a web-only
microphoneDeviceId; update the logic around
useNativeMacScreenCapture/microphoneEnabled so that before calling
window.electronAPI.startNativeScreenRecording you (a) attempt to resolve a
native ID via listNativeMicrophones using micLabel and, if micLabel is absent,
try to map from the web microphoneDeviceId to a native id as a fallback, and (b)
if no native id (nativeMicId) is found, pass null/undefined (not the original
web microphoneDeviceId) for the microphoneDeviceId argument to
startNativeScreenRecording so the native side won’t receive an incompatible web
ID; touch the code that sets nativeMicId and the call to
startNativeScreenRecording to implement this behavior (referencing
useNativeMacScreenCapture, micLabel, nativeMicId, microphoneDeviceId,
listNativeMicrophones, and startNativeScreenRecording).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 1388da0c-fa89-4968-b3c7-0cc0e88eea57
📒 Files selected for processing (6)
electron/electron-env.d.tselectron/ipc/register/recording.tselectron/native/ScreenCaptureKitRecorder.swiftelectron/preload.tssrc/components/video-editor/videoPlayback/zoomRegionUtils.tssrc/hooks/useScreenRecorder.ts
On the native macOS path the web MediaDevices deviceId can't match a Core Audio uniqueID, so falling back to it when native resolution fails just reintroduces the silent default-mic fallback. Pass only the resolved uniqueID on mac (undefined when unresolved) and let the helper's label matching be the backstop; keep the web id for the non-mac path.
Problem
On macOS (native ScreenCaptureKit backend), selecting a specific microphone in Recordly has no effect — the recorder always captures the system default input device. If the default is a poor/far device (e.g. a Bluetooth speakerphone running in HFP/SCO narrowband mode), recordings come out muffled and quiet regardless of what the user picked.
Root cause
The renderer passed the web
MediaDevicesdeviceId (an opaque, per-origin hashed string) plus the web device label to the native helper. The Swift helper then tried to match those againstAVCaptureDevice:deviceIdnever equals a Core AudiouniqueID, so that match always failed.AVCaptureDevice.localizedNameverbatim (and can be empty when the capturing context lacks mic permission), so exact label matching usually failed too.When both failed,
resolveMicrophoneCaptureDeviceIDreturnedniland ScreenCaptureKit silently fell back to the system default mic.Fix
ScreenCaptureKitRecorder.swift): add a--list-microphonesmode that prints the real Core Audio input devices (uniqueID+localizedName) as JSON. Runs before any screen-capture preflight so enumeration never triggers a Screen Recording permission prompt.list-native-microphonesIPC that runs the helper in that mode and returns the device list.useScreenRecorder.ts): at record-start, resolve the selected mic to its real Core AudiouniqueIDvia that enumeration and pass it asmicrophoneDeviceId, so ScreenCaptureKit records the chosen device.uniqueID, then fall back to tolerant (case-insensitive / containment) label matching as a backstop.Note on the second commit
fix(build): remove orphaned connected-zoom transition dead codeis included becausemaincurrently failstsc(getConnectedRegionTransitionand its only-local helpers inzoomRegionUtils.tsare unreferenced, trippingnoUnusedLocals), which blocks compiling/building this change. Happy to split it into its own PR if preferred.Testing
npx tscclean;vitestsuites pass.swiftcand verified--list-microphonesreturns the real devices with theiruniqueIDs.Found while investigating #662.
Summary by CodeRabbit
New Features
Bug Fixes