Appearance
System Audio Recording
System audio recording lets you capture exactly what users hear, which is useful for apps like meeting recorders.
RecordKit supports two ways to record system audio: Core Audio and ScreenCaptureKit. By default, the most appropriate backend is selected, which works well for most setups, but you can also explicitly choose the backend when needed.
Record All System Audio
Recording all system audio is the simplest setup:
swift
let recorder = RKRecorder([
.systemAudio()
])
try await recorder.start()ts
const recorder = await recordkit.createRecorder({
items: [
{
type: 'systemAudio'
}
]
})
await recorder.start()Prerequisite
Add NSAudioCaptureUsageDescription to your app's Info.plist. Without it, Core Audio system-audio recordings will be silent.
Choose a Backend
Default (Recommended)
- OS support: all macOS versions supported by RecordKit (macOS 13+)
- Best fit: maximum compatibility with automatic fallback
This setting will use Core Audio on macOS 14.2+ and ScreenCaptureKit on older macOS versions.
swift
let recorder = RKRecorder([
.systemAudio(backend: .default) // You can also omit the backend to use default
])ts
// Omit backend to use RecordKit's default backend selection
const recorder = await recordkit.createRecorder({
items: [
{
type: 'systemAudio'
}
]
})Core Audio
Core Audio has a friendlier flow where the user can grant system audio recording permissions with one click. This also ensures the user the app can't also capture the screen. It is supported on macOS 14.2+.
swift
let recorder = RKRecorder([
.systemAudio(backend: .coreAudio)
])ts
const recorder = await recordkit.createRecorder({
items: [
{
type: 'systemAudio',
backend: 'coreAudio'
}
]
})ScreenCaptureKit
ScreenCaptureKit is available from macOS 12.3+. It uses Screen Recording permission, which the user needs to enable in System Settings. After enabling, the app must be restarted for it to take effect.
swift
let recorder = RKRecorder([
.systemAudio(backend: .screenCaptureKit)
])ts
const recorder = await recordkit.createRecorder({
items: [
{
type: 'systemAudio',
mode: 'exclude',
backend: 'screenCaptureKit',
excludeOptions: ['currentProcess']
}
]
})Permissions
Core Audio requires NSAudioCaptureUsageDescription in your app's Info.plist.
Use RecordKit's permission helpers to check and request the correct permission for your chosen backend:
swift
let backend: RKRecorder.SystemAudioBackend = .default
if !RKAuthorization.systemAudioRecording(backend: backend) {
try await RKAuthorization.requestSystemAudioRecording(backend: backend)
}ts
const backend = 'default' // 'default' | '_beta_coreAudio' | 'screenCaptureKit'
if (!(await recordkit.getSystemAudioRecordingAccess({ backend }))) {
await recordkit.requestSystemAudioRecordingAccess({ backend })
}TIP
On macOS 26+, Screen Recording permission also grants access to system audio via Core Audio. If your app is already granted this permission, you're already covered, but still include NSAudioCaptureUsageDescription in your Info.plist.
Recording Modes
Record Everything
Use systemAudio() to record all system audio.
swift
let recorder = RKRecorder([
.systemAudio()
])ts
const recorder = await recordkit.createRecorder({
items: [
{
type: 'systemAudio',
mode: 'exclude',
excludeOptions: ['currentProcess']
}
]
})Excluding Specific Apps
Use exclude mode to remove apps you do not want in the mix, for example Apple Music or Spotify.
swift
let apps = RKRunningApplication.applications()
let excluded = apps
.filter { $0.bundleIdentifier == "com.apple.Music" || $0.bundleIdentifier == "com.spotify.client" }
.map(\.id)
var options: Set<RKRecorder.SystemAudioExcludeOptions> = [.currentProcess]
options.formUnion(excluded.map { .processID($0) })
let recorder = RKRecorder([
.systemAudio(excluding: options)
])ts
const apps = await recordkit.getRunningApplications()
const excludedProcessIDs = apps
.filter((app) => app.bundle_identifier === 'com.apple.Music' || app.bundle_identifier === 'com.spotify.client')
.map((app) => app.id)
const recorder = await recordkit.createRecorder({
items: [
{
type: 'systemAudio',
mode: 'exclude',
excludeOptions: ['currentProcess'],
excludedProcessIDs
}
]
})Record Specific Apps
Use include mode when you want audio from selected apps only, for example Zoom.
swift
let apps = RKRunningApplication.applications()
let zoomIDs = apps
.filter { $0.bundleIdentifier == "us.zoom.xos" }
.map(\.id)
let recorder = RKRecorder([
.systemAudio(includedApplicationIDs: zoomIDs)
])ts
const apps = await recordkit.getRunningApplications()
const zoomIDs = apps
.filter((app) => app.bundle_identifier === 'us.zoom.xos')
.map((app) => app.id)
const recorder = await recordkit.createRecorder({
items: [
{
type: 'systemAudio',
mode: 'include',
includedApplicationIDs: zoomIDs
}
]
})TIP
Some apps output audio from background processes. For supported browsers such as Safari and Chrome, RecordKit handles this process routing automatically.