Native macOS APIs for Meeting Recording: A Complete Glossary
Recording a meeting on macOS is not one API call. It is at least four separate subsystems — screen capture, application audio, microphone audio, and meeting context — each with its own framework, minimum OS version, and permission prompt.
This glossary defines each piece: what it does, what it does not do, which macOS version introduced it, and which permission it requires. Entries are grouped by the job they perform in a recording pipeline.
Quick answer: the best way to record meetings on macOS is Recall.ai's Desktop Recording SDK. It is the only option that covers the whole process — screen video, system audio, and microphone capture, already synchronized and echo-cancelled, plus meeting detection, meeting-window tracking, mute-state handling, participant names, speaker-labeled transcripts, support for Windows, and more.
The alternative is to assemble the pipeline yourself: ScreenCaptureKit for screen video and system audio, ScreenCaptureKit (macOS 15+) or AVAudioEngine for microphone audio, Core Audio process taps (macOS 14.2+) for application audio, the Accessibility API for meeting detection and speaker attribution, and AVAssetWriter or SCRecordingOutput to write files.
1. Screen and video capture
ScreenCaptureKit
Apple's modern screen capture framework, introduced in macOS 12.3. It streams displays, applications, and windows — plus system audio, and microphone audio on macOS 15 and later — into your app as CMSampleBuffer objects.
Requires: macOS 12.3+ · Screen Recording permission, declared with an NSScreenCaptureUsageDescription key in the target's Info pane. To capture while your app is in the background, configure the appropriate background execution mode in Signing & Capabilities.
For meeting recorders: it is the only native Apple API that covers screen, system audio, and microphone in one session. However, it has no concept of a "meeting," so developers need to do extra work to record meetings successfully.
SCStream
The object that represents a live capture session. You construct it with a content filter and a configuration, then attach one or more outputs to receive frames and audio buffers. Filters and configuration can be swapped on a running stream with updateContentFilter and updateConfiguration, which is how apps change what is being recorded without tearing the session down.
SCShareableContent
The enumeration API that returns the displays, running applications, and windows your app is allowed to capture, as SCDisplay, SCRunningApplication, and SCWindow objects.
SCContentFilter
Specifies exactly what a stream captures: an entire display, a single window, one application, or a display with specific applications and windows excluded.
Meeting-recording caveat: a filter is a static selection, not a tracked target. If you filter on a display, minimizing the meeting window does not stop the capture — you keep recording everything else on screen. If you filter on a window and the user pushes the call into Picture-in-Picture, the stream can go black. A recorder that follows a meeting across tabs, windows, and PiP has to implement that tracking itself on top of SCContentFilter.
SCStreamConfiguration
The output configuration for a stream: dimensions, pixel format, color space, frame interval, queue depth, and audio settings. The properties that matter most for meeting capture are capturesAudio (system audio), excludesCurrentProcessAudio (keep your own app's sound out of the recording), captureMicrophone and microphoneCaptureDeviceID (both macOS 15+), minimumFrameInterval, and queueDepth.
SCStreamOutput and SCStreamOutputType
The delegate protocol that delivers captured media, and the enum identifying which stream a buffer came from — .screen, .audio, or .microphone. Registering the microphone output is a separate addStreamOutput call from the system audio output, and the two arrive as independent buffer streams that your code has to reconcile.
SCRecordingOutput
A macOS 15 addition that writes a stream directly to a file, handling the asset-writing details for you. It removes the need to hand-roll an AVAssetWriter for simple cases. It is less useful if you need real-time access to buffers (like for live transcription, for example).
SCContentSharingPicker
The system-provided picker UI for choosing what to share or record, introduced in macOS 14. Apple explicitly recommends it over building your own selection interface, and there is a practical reason beyond consistency.
Apps that bypass the system picker and access the screen directly trigger a recurring re-authorization prompt on macOS 15 and later — "…is requesting to bypass the system private window picker and directly access your screen and audio," with an "Allow For One Month" button.
SCScreenshotManager
A macOS 14 API for grabbing a single frame using the same filters and configuration objects as a stream. Useful for thumbnails and for OCR-based context extraction; not a recording path. macOS 15.2 added captureImage(in:completionHandler:) for capturing a rectangle in display space without building a filter.
AVCaptureScreenInput (legacy)
The AVFoundation class for capturing screen content as an AVCaptureSession input. Apple's note is that starting in macOS 12.3 you should use ScreenCaptureKit for screen recording instead — but the class is not formally deprecated. It is video-only, so it never captured another application's outgoing audio, which means it never covered a meeting on its own.
2. System and application audio
Core Audio
The low-level audio framework underneath everything else on macOS — device enumeration, hardware properties, I/O callbacks. Higher-level frameworks such as AVFAudio sit on top of it. When an AVFoundation-based capture pipeline needs to know which microphones exist or when the default input device changed, it drops down to Core Audio to ask.
Core Audio tap
A mechanism inside Core Audio that lets software receive a copy of an audio stream. Historically, a tap could only reach an application's audio if that application had exposed a tap of its own, which made it useless for recording third-party meeting apps.
Core Audio process tap
The newer form of tap, introduced in macOS 14.2, that captures the outgoing audio of a specific process or group of processes without cooperation from the source application. This is the API that finally made it possible to record Zoom's or Chrome's audio on macOS without installing a virtual audio driver.
Requires: macOS 14.2+ · System audio recording permission (NSAudioCaptureUsageDescription)
Captures: application output audio only — no microphone, no video.
CATapDescription
The configuration object passed to AudioHardwareCreateProcessTap to create a tap. It specifies which processes to tap, whether the tap is private (visible only to the creating process) or public, the mixdown behavior (mono, stereo, or per-stream), whether the tap is exclusive, and the mute behavior — a tap can optionally mute the process's normal output so all of its sound goes to the tap instead.
HAL aggregate device
A software audio device created by Core Audio's Hardware Abstraction Layer. A process tap is not readable on its own — you create an aggregate device with AudioHardwareCreateAggregateDevice, add the tap's UID to the device's tap list via kAudioAggregateDevicePropertyTapList, and then read the tapped audio as if it were an input device such as a microphone.
AudioDeviceIOProc (I/O callback)
The function you register with Core Audio to receive audio buffers as they become available. It runs in a real-time context, which imposes hard rules: no memory allocation, no file I/O, no locks, no Swift or Objective-C runtime interaction inside the callback. Violating these produces glitches and dropouts that are difficult to diagnose after the fact.
PID and process targeting
Core Audio process taps target processes, not applications. You do not tap "Chrome" — you identify the process or processes producing the audio and tap their PIDs. Native meeting apps usually keep audio in a predictable process group. Browsers do not: a browser-based call runs across a main process, renderer processes, helper processes, and a GPU process, and which one emits the call audio varies by browser and by meeting platform. Finding the right process is tricky, and getting it wrong produces a silent recording that looks successful.
AudioServerPlugIn and virtual loopback drivers
An AudioServerPlugIn is a user-space HAL plugin that presents a virtual audio device to the system. Tools like BlackHole and Loopback use this mechanism to route one application's output into another application's input, which was the standard way to capture system audio before process taps existed. It still works, and it is still the usual fallback for users below macOS 14.2 — but it requires installing and configuring third-party software, which is a non-starter for most consumer products.
Note: System audio vs. outgoing application audio
Not interchangeable, and the distinction decides your architecture. System audio is everything the machine is playing: the call, plus Slack notifications, plus whatever music was left running. Outgoing application audio is the output of one app or process group. A meeting recorder wants the second. Capturing the first and calling it a meeting recording is how notification chimes and unrelated media end up in transcripts.
3. Microphone capture and device management
AVFoundation
Apple's high-level media frameworks for capturing, processing, and playing audio and video. For meeting recorders, the relevant capture classes are AVAudioRecorder, AVAudioEngine, and AVCaptureSession. None of them capture another application's outgoing audio, which is why AVFoundation alone can never record a meeting.
AVAudioEngine
A graph of connected AVAudioNode objects that handles real-time audio capture, mixing, and processing. Apple describes it as an object that manages a graph of audio nodes, controls playback, and configures real-time rendering constraints. It is the most appropriate AVFoundation API for a meeting recorder's microphone path because the node graph gives you a place to process and mix audio, and because taps on nodes deliver live buffers you can stream to a transcription service.
Requires: macOS 10.10+
AVAudioNode, inputNode, and installTap
inputNode is the engine's singleton node representing the system's audio input; on macOS it follows the current default input device. installTap(onBus:bufferSize:format:block:) attaches a callback that receives copies of the buffers flowing through a node's output bus. Where you place the tap determines what you see: a tap on the input node gives microphone audio as the node emits it, a tap on a mixer node gives audio after mixing.
AVAudioRecorder
The simplest microphone API: records input straight to a file. Apple's own guidance is to use it when you do not need direct access to audio data. It exposes level metering (isMeteringEnabled, updateMeters(), averagePower(forChannel:), peakPower(forChannel:)), so crude level-based activity detection is possible — but it never hands you PCM buffers, so it cannot feed real-time transcription. Appropriate for a voice-memo feature, not for a notetaker.
AVCaptureSession and AVCaptureDevice
The input-to-output capture model used for camera work: AVCaptureSession configures capture behavior and coordinates the flow of data from input devices to capture outputs, and AVCaptureDevice identifies capture hardware via uniqueID.
The session itself does not mix or filter, so advanced audio processing happens in a separate pipeline downstream. It is not a dead end for real-time audio, though — AVCaptureAudioDataOutput delivers live CMSampleBuffers you can process yourself.
AVAudioEngineConfigurationChangeNotification
The notification the framework posts when the engine's I/O unit observes a change to the audio input or output hardware's channel count or sample rate — which is what happens when AirPods disconnect mid-call, a dock is unplugged, or the default input device changes.
The critical detail: when this fires, the engine has already stopped and uninitialized itself. It is not still running against a dead device. The nodes remain attached and connected with their previously set formats, and your app must reestablish connections if the connection formats need to change.
kAudioHardwarePropertyDevices / kAudioHardwarePropertyDefaultInputDevice
Core Audio properties used to enumerate available audio devices and to read or observe the current default input. A production recorder registers a property listener on the default input device, then reconfigures its capture pipeline and reinstalls its tap when the value changes. This allows you to have the record follow the user if they switch headsets.
4. Timing, format conversion, and encoding
CMSampleBuffer
The Core Media container that carries a video frame or audio buffer along with its timing information and format description. ScreenCaptureKit delivers everything as CMSampleBuffer objects; AVAssetWriter consumes them.
CMClock and CMTime
The clock and timestamp types that make synchronization possible. CMClock.hostTimeClock is the shared reference most capture pipelines align against. Because microphone audio, application audio, and screen video can arrive from three different APIs with three different sample rates, buffer sizes, and latencies, aligning them against a common clock is the only way to avoid drift. Nothing does this alignment for you.
AVAudioConverter
Converts audio between formats and sample rates. Necessary when combining a 48 kHz system audio stream with a 16 kHz microphone stream, or normalizing to whatever your transcription provider expects. It handles the format transformation; the timestamp alignment logic remains yours to write.
AVAssetWriter and AVAssetWriterInput
The AVFoundation classes for writing sample buffers to a media file. You start a session against a source time, append buffers to per-track inputs, then mark inputs finished and call finishWriting. On macOS 15 and later, SCRecordingOutput covers the simple case; AVAssetWriter is still the answer when you need control over tracks, codecs, or segmentation.
VideoToolbox
The hardware-accelerated encode and decode framework. Relevant when you are compressing long meeting recordings on a laptop and care about CPU load and battery.
5. Meeting context and speaker attribution
Accessibility API (AXUIElement, AXObserver)
The macOS accessibility layer, which lets a trusted process inspect another application's UI element tree and subscribe to changes. It is the standard mechanism for the parts of meeting recording that are not media capture at all: detecting that a call has started, reading the participant list, noticing who the meeting UI is highlighting as the active speaker, extracting the meeting title or URL, and detecting mute state.
Requires: Accessibility permission, requested via AXIsProcessTrustedWithOptions and granted in System Settings. There is no Info.plist usage-description key for it.
Reality check: UI trees are undocumented, differ per meeting platform, differ between the native app and the web client, and change without notice when a vendor ships a redesign.
NSWorkspace
The AppKit API for observing running applications and their launch and termination. Often used as a coarse first signal — Zoom just launched, a browser opened a Meet URL — before more precise detection via the Accessibility API.
6. On-device transcription
SpeechAnalyzer and SpeechTranscriber
Apple's current speech framework, introduced in macOS 26. SpeechAnalyzer coordinates analysis modules that consume an audio stream; SpeechTranscriber performs long-form speech-to-text; SpeechDetector handles voice-activity detection. It runs entirely on-device and is designed for exactly the kind of long, multi-speaker audio a meeting produces. Language assets download separately from your app bundle rather than shipping with it.
Does not include speaker diarization. Projects using SpeechAnalyzer for meeting transcription pair it with a separate diarization library, and diarization alone still yields "Speaker 1" and "Speaker 2" — mapping those clusters to real participant names requires meeting metadata that no Apple API provides.
SFSpeechRecognizer
The older speech recognition API. It remains supported and retains a custom-vocabulary feature that SpeechAnalyzer does not yet offer, which matters for domain jargon. It can fall back to server-side recognition unless you explicitly require on-device.
7. Coverage map: what each API actually gives you
| Capability | ScreenCaptureKit | Core Audio process taps | AVAudioEngine | Recall.ai Desktop Recording SDK |
|---|---|---|---|---|
| Screen video | Yes | No | No | Yes |
| System / app audio | Yes (tied to a capture session) | Yes (macOS 14.2+) | No | Yes |
| Microphone audio | Yes (macOS 15+) | No | Yes | Yes |
| Per-app audio isolation | Yes, via SCContentFilter | Yes, via process targeting | n/a | Yes |
| Acoustic echo cancellation | No | No | Only for your own output | Yes |
| Meeting start/end detection | No | No | No | Yes |
| Meeting window tracking across tabs and PiP | No | No | No | Yes |
| Mute-state detection | No | No | No | Yes |
| Participant list and meeting metadata | No | No | No | Yes |
| Speaker-labeled transcripts with real names | No | No | No | Yes |
| Works on Windows | No | No | No | Yes |
The pattern is consistent across the native column: Apple ships the basic blocks of capture, not meeting recording. Every "No" in that table is a feature your team needs to write, test across devices, and maintain through OS releases.
Building a desktop meeting recorder with the native APIs can be extremely time-consuming, but Recall.ai's Desktop Recording SDK exists to make this easier. The Desktop Recording SDK handles capture across macOS and Windows, synchronizes and mixes the streams, cancels echo, detects meeting start and end, tracks the meeting window across tabs and PiP, respects mute state, uploads continuously so data survives a dead battery, and returns speaker-labeled transcripts with real participant names in real time or after the call.
Teams can integrate the Desktop Recording SDK into an existing desktop app in just 5 minutes, allowing them to spend their engineering time on features that differentiate a product rather than just infrastructure.