Record your screen and your Mac's audio at once, from the terminal, with no loopback driver — no BlackHole, no Loopback, no "route the speakers into the microphone" hack.
recThat's it. It starts recording the whole screen + all system audio immediately and
saves ./yyyy-MM-dd-HH-mm-ss.mov in the folder you ran it from. Press Ctrl-C to
stop and finalize.
macOS's built-in recorders — QuickTime Player and the ⌘⇧5 Screenshot toolbar — only offer a microphone picker. Apple omits system-audio capture from the built-in recorder on purpose, which is why everyone reaches for a virtual-audio-device hack (BlackHole/Loopback) that pretends to be a microphone.
But the capability ships in the OS: ScreenCaptureKit's
SCStreamConfiguration.capturesAudio pulls audio straight off the system audio
engine, and an app-scoped SCContentFilter can capture only one app's sound. This
is a ~300-line Swift CLI that surfaces exactly that. Apple-frameworks only — no Homebrew,
no dependencies.
git clone https://github.com/esaruoho/apple-rec.git
cd apple-rec
./build.sh # compiles screen-audio-record (swiftc)
ln -s "$PWD/rec" /usr/local/bin/rec # optional: put `rec` on your PATHrec also auto-builds the binary on first run, so ./rec works straight after clone.
Requires macOS 13+ (ScreenCaptureKit); --also-mic needs macOS 15+. On first
run, macOS asks for Screen Recording permission for your terminal — approve it (System
Settings ▸ Privacy & Security ▸ Screen Recording). macOS Sequoia re-asks weekly / after
reboot; that's an OS policy the tool can't suppress.
rec # whole screen + ALL system audio → ./<timestamp>.mov
rec --app Renoise # screen + ONLY that app's audio (nothing else leaks in)
rec --mic # start with your microphone recording too (2nd audio track)
rec --reveal # reveal + select the finished file in Finder on stop
rec --out ~/demo.mov # custom output path
rec --list # list displays + audible running apps (for --app)- Stop a terminal recording with Ctrl-C (or type
q+ Enter) — it catches the signal and finalizes the.mov, then prints the final recording length and whether the mic was recorded. Do not re-runrecto stop (that starts a second recording). On start it also states plainly whether the microphone is ON. - Toggle the mic on/off mid-recording without stopping: send the process
SIGUSR1, e.g.kill -USR1 $(pgrep -n screen-audio-record). The mic goes to its own track, so muting just stops writing mic samples. Start muted (default) or hot (--mic). --app <name>overrides--system-audio— single-app audio wins.- Output is one
.mov: H.264 video + AAC audio (a 2nd AAC track for the mic when used), muxed viaAVAssetWriter.
Pass --mic (or toggle it on live). System audio and the microphone are captured as two
separate audio tracks in the same .mov — so Final Cut / Premiere / DaVinci can balance
them independently.
rec --mic also writes a
<name>-flat.mov with system + mic mixed into one track — that's the file you upload.
(iMovie can't split embedded tracks either; see rec-audio below.)
rec-audio split recording.mov # → recording-system.m4a + recording-mic.m4a
rec-audio flatten recording.mov [-o out] # → recording-flat.mov (video + one mixed track)splitextracts each audio stream to its own.m4a. iMovie recipe: import the.mov(video + system audio), then dragrecording-mic.m4aonto the timeline as a second audio track — now you can balance voice vs app sound independently.flattenmixes system + mic into one track on a video-passthrough.mov(no re-encode, no quality loss) viaAVAssetReaderAudioMixOutput. Plays both everywhere — QuickTime, iMovie, YouTube. This is what--auto-flattenruns for you.
rec-subtitle recording.mov # → recording.srt (upload to YouTube as captions)
rec-subtitle recording.mov --burn # → recording-subtitled.mov (subtitles painted in)- Sidecar: transcribes the audio to
recording.srt. Upload the video + this.srtas a caption track.--mic recording-mic.m4atranscribes the voice-only track for a cleaner result. --burn: hard-paints the subtitles into a new-subtitled.mov— Apple-nativeAVVideoCompositionCoreAnimationTool, white text + black outline, bottom-center, timed per cue.- Transcription is the one feature that needs a 3rd-party tool (the openai-whisper
whisperCLI). Install it once:./install-deps.sh(runspip install openai-whisper- checks ffmpeg).
--model tiny|base|small|medium|large-v3trades speed for accuracy (defaultbase). Everything else — recording, PiP, flatten, burn-in — is Apple-native, no deps.
- checks ffmpeg).
rec --mic --pip --burn # record (screen + system + mic + webcam circle) → on Ctrl-C:
# flatten (YouTube) + transcribe + burn subtitles, all in one gorec is a thin wrapper over screen-audio-record, which you can call directly for full
control (e.g. --system-audio vs --app, --display <n>, --fps <n>):
./screen-audio-record --list
./screen-audio-record --app Renoise --out ~/take.mov
./screen-audio-record --system-audio --fps 30 --out ~/take.movSCContentFilterselects the display, or the display including a single application (for per-app audio isolation).SCStreamConfiguration:capturesAudio = true,excludesCurrentProcessAudio = true, 48 kHz stereo; optionalcaptureMicrophone = true(macOS 15+ native mic, noAVCaptureSession).- An
SCStreamdelivers.screen(BGRA frames),.audio, and optionally.microphonesample buffers, which are appended to anAVAssetWriter(.mov, H.264 + AAC). - Ctrl-C (
SIGINT) is handled by aDispatchSourcethat stops capture, marks the writer inputs finished, and finalizes the file.
MIT — see LICENSE.
Mirror of bin/screen-audio-record + bin/rec from
esaruoho/apple. The standalone repo is canonical on
divergence.