Capso Screenshot Macos

reason-machines/trending-skills/skills/capso-screenshot-macos

作者 reason-machines2384a003145a无许可证83 个星标收录于 2026年10月8日更新于 2026年10月8日仓库3个月前更新

Expert skill for Capso, the open-source macOS screenshot and screen recording app built with Swift 6 and SwiftUI — covers architecture, building from source, package APIs, and contributing.

AI 生成的概览

介绍开源 macOS 截图与录屏应用 Capso 及其 Swift 软件包和 API 的参考指南。

功能
该技能介绍 Capso——一款使用 Swift 6 和 SwiftUI 构建的原生 macOS 截图与录屏应用,并说明其模块化 SPM 软件包架构。它讲解如何安装或从源码构建该应用,以及如何将 CaptureKit、AnnotationKit、OCRKit、RecordingKit、CameraKit、ExportKit、SharedKit 等独立软件包嵌入自己的应用。内容包含 API 用法示例、SwiftUI 集成方式、所需权限与 Info.plist 键、测试命令和故障排查说明。
适用场景
适用于为 macOS 应用添加截图、录屏、标注、OCR 或摄像头画中画功能,或从源码构建 Capso 的场景。也适合希望参与 Capso 开源项目贡献的开发者。
运行要求
需要 macOS 15.0 及以上、Xcode 16 及以上,从源码构建还需 XcodeGen;所述软件包依赖 ScreenCaptureKit、AVFoundation、Vision 和 Carbon。必须授予屏幕录制、摄像头和麦克风权限,克隆仓库或下载发行版需要网络访问。该技能仅包含说明文档,不含脚本。

Capso Screenshot & Screen Recording Skill

Skill by ara.so — Daily 2026 Skills collection.

Capso is a fully native, open-source macOS screenshot and screen recording app — a free alternative to CleanShot X. Built with Swift 6.0 and SwiftUI targeting macOS 15.0+. Its key strength for developers is a modular SPM architecture: 8 independent packages (CaptureKit, AnnotationKit, OCRKit, etc.) you can embed individually in your own app.


Installation

Download Pre-built App

bash
# Homebrew (recommended)brew tap lzhgus/tapbrew install --cask capso

Or download the signed DMG from GitHub Releases.

Build from Source

Requirements: Xcode 16+, macOS 15.0+, XcodeGen

bash
brew install xcodegen
git clone https://github.com/lzhgus/Capso.gitcd Capsoxcodegen generateopen Capso.xcodeproj# Press Cmd+R to build and run

CLI build:

bash
xcodegen generatexcodebuild -project Capso.xcodeproj \  -scheme Capso \  -configuration Release \  build

Project Architecture

Capso/├── App/                     # Thin SwiftUI + AppKit shell│   ├── CapsoApp.swift       # @main entry point│   ├── MenuBar/│   ├── Capture/│   ├── Recording/│   ├── Camera/│   ├── AnnotationEditor/│   ├── OCR/│   ├── QuickAccess/│   └── Preferences/├── Packages/│   ├── SharedKit/           # Settings, permissions, utilities│   ├── CaptureKit/          # ScreenCaptureKit wrapper│   ├── RecordingKit/        # Screen recording engine│   ├── CameraKit/           # AVFoundation webcam capture│   ├── AnnotationKit/       # Drawing/annotation system│   ├── OCRKit/              # Vision framework OCR│   ├── ExportKit/           # Video/GIF/image export│   └── EffectsKit/          # Cursor effects, click highlights└── project.yml              # XcodeGen project definition

The app shell is intentionally thin — all logic lives in packages. This means you can pull individual packages into your own app via SPM.


Using Capso Packages in Your Own App

Add a package as a local or remote SPM dependency in your Package.swift:

swift
// Package.swiftlet package = Package(    name: "MyApp",    platforms: [.macOS(.v15)],    dependencies: [        // Remote (once published to a registry or via exact path)        .package(path: "../Capso/Packages/CaptureKit"),        .package(path: "../Capso/Packages/AnnotationKit"),        .package(path: "../Capso/Packages/OCRKit"),    ],    targets: [        .target(            name: "MyApp",            dependencies: [                "CaptureKit",                "AnnotationKit",                "OCRKit",            ]        ),    ])

Package API Examples

CaptureKit — Screen Capture

CaptureKit wraps ScreenCaptureKit for area, fullscreen, and window capture.

swift
import CaptureKit
// Area capturelet captureManager = CaptureManager()
// Fullscreen captureTask {    let image: NSImage = try await captureManager.captureFullscreen()    // use image}
// Window capture — pass SCWindow from ScreenCaptureKitTask {    let content = try await SCShareableContent.excludingDesktopWindows(false, onScreenWindowsOnly: true)    if let window = content.windows.first {        let image: NSImage = try await captureManager.captureWindow(window)    }}
// Area capture with a selection rectTask {    let rect = CGRect(x: 100, y: 100, width: 800, height: 600)    let image: NSImage = try await captureManager.captureArea(rect)}

RecordingKit — Screen Recording

swift
import RecordingKit
let recorder = ScreenRecorder()
// Configure recordingvar config = RecordingConfiguration()config.includesSystemAudio = trueconfig.includesMicrophone = falseconfig.outputFormat = .mp4   // or .gifconfig.quality = .maximum    // .social, .web
// Start recording a regionTask {    let outputURL = URL(fileURLWithPath: "/tmp/recording.mp4")    try await recorder.startRecording(        region: CGRect(x: 0, y: 0, width: 1920, height: 1080),        to: outputURL,        configuration: config    )}
// Pause / resumerecorder.pause()recorder.resume()
// Stop and get final URLTask {    let finalURL = try await recorder.stopRecording()    print("Saved to \(finalURL)")}

CameraKit — Webcam PiP

swift
import CameraKit
let cameraManager = CameraManager()
// Request permission and start previewTask {    let granted = await cameraManager.requestPermission()    guard granted else { return }        // Get AVCaptureVideoPreviewLayer for embedding in a view    let previewLayer = try await cameraManager.startCapture()        // Set PiP shape    cameraManager.pipShape = .circle      // .circle, .square, .portrait, .landscape}
// Stop capturecameraManager.stopCapture()

AnnotationKit — Drawing & Annotation

swift
import AnnotationKit
// Create an annotation canvas over an NSImagelet sourceImage = NSImage(named: "screenshot")!let canvas = AnnotationCanvas(image: sourceImage)
// Add annotations programmaticallylet arrow = ArrowAnnotation(    from: CGPoint(x: 50, y: 50),    to: CGPoint(x: 200, y: 200),    color: .red,    strokeWidth: 3)canvas.addAnnotation(arrow)
let rect = RectangleAnnotation(    frame: CGRect(x: 100, y: 100, width: 300, height: 150),    color: .blue,    strokeWidth: 2,    filled: false)canvas.addAnnotation(rect)
let text = TextAnnotation(    text: "Look here!",    position: CGPoint(x: 110, y: 110),    fontSize: 18,    color: .white)canvas.addAnnotation(text)
// Undo / redocanvas.undo()canvas.redo()
// Export annotated imagelet result: NSImage = canvas.renderToImage()

Screenshot Beautification (AnnotationKit)

swift
import AnnotationKit
let beautifier = ScreenshotBeautifier(image: rawImage)beautifier.backgroundColor = .systemBlue   // or gradient/custombeautifier.padding = 40beautifier.cornerRadius = 12beautifier.shadowRadius = 20beautifier.shadowOpacity = 0.4
let beautified: NSImage = beautifier.render()

OCRKit — Text Recognition

swift
import OCRKit
let ocrEngine = OCREngine()
// Instant OCR on an NSImage — returns plain textTask {    let text: String = try await ocrEngine.recognizeText(in: image)    print(text)    // Copy to clipboard    NSPasteboard.general.clearContents()    NSPasteboard.general.setString(text, forType: .string)}
// Visual OCR — returns bounding boxes + text for each blockTask {    let blocks: [OCRTextBlock] = try await ocrEngine.recognizeBlocks(in: image)    for block in blocks {        print("Text: \(block.text), Bounds: \(block.boundingBox)")    }}

ExportKit — Video & GIF Export

swift
import ExportKit
let exporter = MediaExporter()
// Export recorded video with quality presetTask {    let inputURL = URL(fileURLWithPath: "/tmp/raw_recording.mp4")    let outputURL = URL(fileURLWithPath: "/tmp/final.mp4")        try await exporter.exportVideo(        from: inputURL,        to: outputURL,        quality: .social   // .maximum, .social, .web    )}
// Export as GIFTask {    let inputURL = URL(fileURLWithPath: "/tmp/raw_recording.mp4")    let outputURL = URL(fileURLWithPath: "/tmp/output.gif")        try await exporter.exportGIF(        from: inputURL,        to: outputURL,        fps: 15,        scale: 0.75    )}

SharedKit — Permissions & Settings

swift
import SharedKit
// Check and request screen recording permissionlet permissionManager = PermissionManager()
Task {    let hasScreen = await permissionManager.requestScreenRecordingPermission()    let hasCamera = await permissionManager.requestCameraPermission()    let hasMic = await permissionManager.requestMicrophonePermission()}
// Access shared app settingslet settings = CapsoSettings.sharedsettings.screenshotShortcut = "⌘⇧4"settings.defaultSaveLocation = URL(fileURLWithPath: "/Users/me/Screenshots")settings.showCountdownBeforeRecording = truesettings.countdownSeconds = 3

SwiftUI Integration Pattern

Embed a capture button in a SwiftUI view:

swift
import SwiftUIimport CaptureKitimport AnnotationKit
struct ContentView: View {    @State private var capturedImage: NSImage?    @State private var showAnnotationEditor = false    private let captureManager = CaptureManager()
    var body: some View {        VStack {            if let img = capturedImage {                Image(nsImage: img)                    .resizable()                    .scaledToFit()                    .frame(maxWidth: 600)                                Button("Annotate") {                    showAnnotationEditor = true                }            }
            Button("Capture Fullscreen") {                Task {                    capturedImage = try? await captureManager.captureFullscreen()                }            }        }        .sheet(isPresented: $showAnnotationEditor) {            if let img = capturedImage {                // Hypothetical SwiftUI wrapper around AnnotationCanvas                AnnotationEditorView(image: img) { annotated in                    capturedImage = annotated                    showAnnotationEditor = false                }            }        }    }}

Running Package Tests

Each package is independently testable:

bash
swift test --package-path Packages/SharedKitswift test --package-path Packages/CaptureKitswift test --package-path Packages/AnnotationKitswift test --package-path Packages/OCRKitswift test --package-path Packages/RecordingKitswift test --package-path Packages/CameraKitswift test --package-path Packages/ExportKitswift test --package-path Packages/EffectsKit

Required Entitlements & Info.plist

Your app using Capso packages needs these permissions:

xml
<!-- Info.plist --><key>NSScreenCaptureUsageDescription</key><string>Required for screenshot and screen recording.</string>
<key>NSCameraUsageDescription</key><string>Required for webcam PiP during screen recording.</string>
<key>NSMicrophoneUsageDescription</key><string>Required to capture microphone audio during recording.</string>
xml
<!-- App.entitlements --><key>com.apple.security.device.camera</key><true/><key>com.apple.security.device.microphone</key><true/><!-- Screen capture is runtime-only via TCC, no entitlement needed -->

Common Patterns

Pin Screenshot to Screen (Always-on-Top)

swift
import AppKit
func pinScreenshot(_ image: NSImage) {    let window = NSPanel(        contentRect: NSRect(x: 100, y: 100, width: image.size.width, height: image.size.height),        styleMask: [.nonactivatingPanel, .titled, .closable, .resizable],        backing: .buffered,        defer: false    )    window.level = .floating           // Always on top    window.isFloatingPanel = true    window.hidesOnDeactivate = false    window.contentView = NSImageView(image: image)    window.makeKeyAndOrderFront(nil)}

Global Keyboard Shortcut (via SharedKit pattern)

swift
import Carbonimport AppKit
// Register a global hotkey for area capturefunc registerCaptureHotkey() {    NSEvent.addGlobalMonitorForEvents(matching: .keyDown) { event in        // Check for ⌘⇧4        if event.modifierFlags.contains([.command, .shift]),           event.keyCode == 21 { // keyCode 21 = '4'            NotificationCenter.default.post(name: .startAreaCapture, object: nil)        }    }}
extension Notification.Name {    static let startAreaCapture = Notification.Name("startAreaCapture")}

Troubleshooting

xcodegen generate fails

  • Ensure XcodeGen ≥ 2.40: brew upgrade xcodegen
  • Check project.yml is not modified with invalid YAML syntax
  • Run xcodegen generate --spec project.yml for explicit path

"Screen Recording permission denied" at runtime

  • Go to System Settings → Privacy & Security → Screen Recording and enable Capso
  • For your own app using CaptureKit, you must trigger the permission prompt first via PermissionManager.requestScreenRecordingPermission()

Build errors with Swift 6 concurrency

  • Capso targets Swift 6 strict concurrency. Ensure all closures that touch UI are @MainActor
  • Add @preconcurrency import for ScreenCaptureKit if you see warnings in Xcode 16

GIF export is slow

  • Lower the fps (e.g. fps: 10) and scale (e.g. scale: 0.5) in ExportKit
  • Use .web quality preset for faster encoding

Camera not showing in PiP

  • Verify camera permission is granted in System Settings
  • Call CameraManager.requestPermission() before startCapture()
  • Ensure your entitlement includes com.apple.security.device.camera

License Note

Capso uses Business Source License 1.1:

  • ✅ Personal use, internal company use, forking, modifying
  • ❌ Selling a competing screen-capture product based on this code
  • ✅ Automatically becomes Apache 2.0 in 2029 per release

When embedding packages in your own non-competing app, you are permitted under BSL 1.1.


Key Links

来源与署名

来源:reason-machines/trending-skills位于skills/capso-screenshot-macos提交2384a00

许可证: 无许可证

内容归原作者所有。SourceWeft 从公开仓库中收录这些内容。

举报或申请下架