Minimal native macOS app that records a webcam timelapse and saves it as an mp4.
Grab the latest prebuilt .app from the Releases page — look for WebcamTimelapse-vX.Y.Z.zip.
The binary is ad-hoc signed (no Apple Developer ID), so macOS Gatekeeper will block it on first launch. To get past that:
- Easy way: right-click
WebcamTimelapse.app→ Open → click Open in the warning dialog. - One-shot CLI fix:
xattr -dr com.apple.quarantine /Applications/WebcamTimelapse.app
Each release also ships a .sha256 file alongside the zip if you want to verify the download.
- Pick any connected camera (built-in or USB).
- Live preview the selected camera as soon as it's chosen — no need to start recording first.
- Capture one still frame every N seconds (default 5s; configurable 1–3600).
- Encode captured frames into an H.264 mp4 played back at M fps (default 30; configurable 1–60).
- On Stop, review the recorded clip inline (with playback controls) and choose Save or Discard.
- Single-window app — no automatic tab bar, no New Window menu item.
- macOS 13 (Ventura) or later
- Xcode 15 or later (project builds with Xcode 26)
- Camera permission (granted on first run)
xcodebuild -project WebcamTimelapse.xcodeproj \
-scheme WebcamTimelapse \
-configuration Debug \
buildThe built .app lives under the configured DerivedData path.
To run from Xcode: open WebcamTimelapse.xcodeproj, pick the WebcamTimelapse scheme, hit Run.
xcodebuild -project WebcamTimelapse.xcodeproj \
-scheme WebcamTimelapse \
-destination 'platform=macOS' \
testCovers:
TimelapseEncoder— synthetic pixel buffers in, readable mp4 outFrameGrabber— timer cadence and stop semanticsSettings— round-trip persistence and clamping
- Launch the app and grant camera access when prompted.
- Select a camera from the picker — the live preview appears immediately.
- Set the capture interval (seconds between frames) and playback FPS.
- Click Start to begin recording. Frame counter and elapsed timer update live.
- Click Stop to finalize. The preview area swaps to a player showing the recorded clip.
- Click Save (⌘↩) to pick a destination via the save sheet, or Discard (⌘⌫) to throw it away. Either action returns to the live camera preview.
WebcamTimelapseApp— SwiftUI App entry, singleWindowscene, ownsAppState.AppState— single source of truth: state enum (idle / requestingPermission / denied / recording / saving / reviewing(URL) / error), frame count, settings, last saved URL.CameraDiscovery—AVCaptureDevice.DiscoverySessionwrapper, publishes connected cameras.CaptureSession— wrapsAVCaptureSession+AVCaptureVideoDataOutput, exposes the latestCVPixelBuffer. Runs whenever a camera is selected.FrameGrabber—DispatchSourceTimerpulling the latest pixel buffer at the configured interval. Attached only while recording.TimelapseEncoder—AVAssetWriter+AVAssetWriterInputPixelBufferAdaptor, H.264 mp4.ContentView/PreviewView/ClipReviewPlayer— SwiftUI shell, liveAVCaptureVideoPreviewLayer, andAVPlayerView-based review player.
- Sandbox is off — keeps save-anywhere behavior simple.
- Frame grab uses
AVCaptureVideoDataOutput(sampled latest pixel buffer), notAVCapturePhotoOutput— no shutter sound, no extra HW negotiation. - Capture session stays alive across recordings so the live preview never blinks out between takes.
- After Stop, the temp mp4 lives in
NSTemporaryDirectoryuntil the user picks Save or Discard; both actions clean up after themselves.