Token导航 LogoToken导航TokenDH.com
开发需要联网github未标认证来源可访问许可证需确认审计通过

axiom-camera-capture-diagAxiom 相机捕捉诊断

Agent Skill

axiom-camera-capture-diag 用于处理 GitHub 仓库、Issue、Pull Request 和代码协作信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要围绕仓库状态、代码变更或协作事项进行整理时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

总安装

188

周安装

8

GitHub Stars

3

下载量

66
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

unknown

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:axiom-camera-capture-diag(Axiom 相机捕捉诊断)
来源仓库:https://github.com/megastep/codex-skills
仓库路径:skills/axiom-camera-capture-diag
安装命令:
npx skills add https://github.com/megastep/codex-skills --skill axiom-camera-capture-diag
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/megastep/codex-skills --skill axiom-camera-capture-diag

简介

axiom-camera-capture-diag 用于处理 GitHub 仓库、Issue、Pull Request 和代码协作信息。

  • 适合在 Codex、Claude、Cursor、Gemini CLI 中围绕仓库状态、代码变更或协作事项进行整理。
  • 可协助分析代码提交历史和协作流程中的关键节点。
  • 安装前需确认权限范围和维护状态,注意是否涉及联网或文件读写。
  • 建议结合原始 README 进一步了解具体用法和功能边界。

SKILL.md

Camera Capture Diagnostics

Systematic troubleshooting for AVFoundation camera issues: frozen preview, wrong rotation, slow capture, session interruptions, and permission problems.

Overview

Core Principle: When camera doesn't work, the problem is usually:

  1. Threading (session work on main thread) - 35%
  2. Session lifecycle (not started, interrupted, not configured) - 25%
  3. Rotation (deprecated APIs, missing coordinator) - 20%
  4. Permissions (denied, not requested) - 15%
  5. Configuration (wrong preset, missing input/output) - 5%

Always check threading and session state BEFORE debugging capture logic.

Red Flags

Symptoms that indicate camera-specific issues:

SymptomLikely Cause
Preview shows black screenSession not started, permission denied, no camera input
UI freezes when opening camerastartRunning() called on main thread
Camera freezes on phone callNo interruption handling
Preview rotated 90° wrongNot using RotationCoordinator (iOS 17+)
Captured photo rotated wrongRotation angle not applied to output connection
Front camera photo not mirroredThis is correct! (preview mirrors, photo does not)
"Camera in use by another app"Another app has exclusive access
Capture takes 2+ secondsphotoQualityPrioritization set to .quality
Session won't start on iPadSplit View - camera unavailable
Crash on older iOSUsing iOS 17+ APIs without availability check

Mandatory First Steps

Before investigating code, run these diagnostics:

Step 1: Check Session State

print("📷 Session state:")
print("  isRunning: \(session.isRunning)")
print("  inputs: \(session.inputs.count)")
print("  outputs: \(session.outputs.count)")

for input in session.inputs {
    if let deviceInput = input as? AVCaptureDeviceInput {
        print("  Input: \(deviceInput.device.localizedName)")
    }
}

for output in session.outputs {
    print("  Output: \(type(of: output))")
}

Expected output:

  • ✅ isRunning: true, inputs ≥ 1, outputs ≥ 1 → Session working
  • ⚠️ isRunning: false → Session not started or interrupted
  • ❌ inputs: 0 → Camera not added (permission? configuration?)

Step 2: Check Threading

print("🧵 Thread check:")

// When setting up session
sessionQueue.async {
    print("  Setup thread: \(Thread.isMainThread ? "❌ MAIN" : "✅ Background")")
}

// When starting session
sessionQueue.async {
    print("  Start thread: \(Thread.isMainThread ? "❌ MAIN" : "✅ Background")")
}

Expected output:

  • ✅ All background → Correct
  • ❌ Any main thread → UI will freeze

Step 3: Check Permissions

let status = AVCaptureDevice.authorizationStatus(for: .video)
print("🔐 Camera permission: \(status.rawValue)")

switch status {
case .authorized: print("  ✅ Authorized")
case .notDetermined: print("  ⚠️ Not yet requested")
case .denied: print("  ❌ Denied by user")
case .restricted: print("  ❌ Restricted (parental controls?)")
@unknown default: print("  ❓ Unknown")
}

Step 4: Check for Interruptions

// Add temporary observer to see interruptions
NotificationCenter.default.addObserver(
    forName: .AVCaptureSessionWasInterrupted,
    object: session,
    queue: .main
) { notification in
    if let reason = notification.userInfo?[AVCaptureSessionInterruptionReasonKey] as? Int {
        print("🚨 Interrupted: reason \(reason)")
    }
}

Decision Tree

Camera not working as expected?
│
├─ Black/frozen preview?
│  ├─ Check Step 1 (session state)
│  │  ├─ isRunning = false → See Pattern 1 (session not started)
│  │  ├─ inputs = 0 → See Pattern 2 (no camera input)
│  │  └─ isRunning = true, inputs > 0 → See Pattern 3 (preview layer)
│
├─ UI freezes when opening camera?
│  └─ Check Step 2 (threading)
│     └─ Main thread → See Pattern 4 (move to session queue)
│
├─ Camera freezes during use?
│  ├─ After phone call → See Pattern 5 (interruption handling)
│  ├─ In Split View (iPad) → See Pattern 6 (multitasking)
│  └─ Random freezes → See Pattern 7 (thermal pressure)
│
├─ Preview/photo rotated wrong?
│  ├─ Preview rotated → See Pattern 8 (RotationCoordinator preview)
│  ├─ Captured photo rotated → See Pattern 9 (capture rotation)
│  └─ Front camera "wrong" → See Pattern 10 (mirroring expected)
│
├─ Capture too slow?
│  ├─ 2+ seconds delay → See Pattern 11 (quality prioritization)
│  └─ Slight delay → See Pattern 12 (deferred processing)
│
├─ Permission issues?
│  ├─ Status: notDetermined → See Pattern 13 (request permission)
│  └─ Status: denied → See Pattern 14 (settings prompt)
│
└─ Crash on some devices?
   └─ See Pattern 15 (API availability)

Diagnostic Patterns

Pattern 1: Session Not Started

Symptom: Black preview, isRunning = false

Common causes:

  1. startRunning() never called
  2. startRunning() called but session has no inputs
  3. Session stopped and never restarted

Diagnostic:

// Check if startRunning was called
print("isRunning before start: \(session.isRunning)")
session.startRunning()
print("isRunning after start: \(session.isRunning)")

Fix:

// Ensure session is started on session queue
func startSession() {
    sessionQueue.async { [self] in
        guard !session.isRunning else { return }

        // Verify we have inputs before starting
        guard !session.inputs.isEmpty else {
            print("❌ Cannot start - no inputs configured")
            return
        }

        session.startRunning()
    }
}

Time to fix: 10 min

Pattern 2: No Camera Input

Symptom: session.inputs.count = 0

Common causes:

  1. Camera permission denied
  2. AVCaptureDeviceInput creation failed
  3. canAddInput() returned false
  4. Configuration not committed

Diagnostic:

// Step through input setup
guard let camera = AVCaptureDevice.default(for: .video) else {
    print("❌ No camera device found")
    return
}
print("✅ Camera: \(camera.localizedName)")

do {
    let input = try AVCaptureDeviceInput(device: camera)
    print("✅ Input created")

    if session.canAddInput(input) {
        print("✅ Can add input")
    } else {
        print("❌ Cannot add input - check session preset compatibility")
    }
} catch {
    print("❌ Input creation failed: \(error)")
}

Fix: Ensure permission is granted BEFORE creating input, and wrap in configuration block:

session.beginConfiguration()
// Add input here
session.commitConfiguration()

Time to fix: 15 min

Pattern 3: Preview Layer Not Connected

Symptom: isRunning = true, inputs configured, but preview is black

Common causes:

  1. Preview layer session not set
  2. Preview layer not in view hierarchy
  3. Preview layer frame is zero

Diagnostic:

print("Preview layer session: \(previewLayer.session != nil)")
print("Preview layer superlayer: \(previewLayer.superlayer != nil)")
print("Preview layer frame: \(previewLayer.frame)")
print("Preview layer connection: \(previewLayer.connection != nil)")

Fix:

// Ensure preview layer is properly configured
previewLayer.session = session
previewLayer.videoGravity = .resizeAspectFill

// Ensure frame is set (common in SwiftUI)
previewLayer.frame = view.bounds

Time to fix: 10 min

Pattern 4: Main Thread Blocking

Symptom: UI freezes for 1-3 seconds when camera opens

Root cause: startRunning() is a blocking call executed on main thread

Diagnostic:

// If this prints on main thread, that's the problem
print("startRunning on thread: \(Thread.current)")
session.startRunning()

Fix:

// Create dedicated serial queue
private let sessionQueue = DispatchQueue(label: "camera.session")

func startSession() {
    sessionQueue.async { [self] in
        session.startRunning()
    }
}

Time to fix: 15 min

Pattern 5: Phone Call Interruption

Symptom: Camera works, then freezes when phone call comes in

Root cause: Session interrupted but no handling/UI feedback

Diagnostic:

// Check if session is still running after returning from call
print("Session running: \(session.isRunning)")
// Will be false during active call, true after call ends

Fix: Add interruption observers (see camera-capture skill Pattern 5)

Key point: Session AUTOMATICALLY resumes after interruption ends. You don't need to call startRunning() again. Just update your UI.

Time to fix: 30 min

Pattern 6: Split View Camera Unavailable

Symptom: Camera stops working when iPad enters Split View

Root cause: Camera not available with multiple foreground apps

Diagnostic:

// Check interruption reason
// InterruptionReason.videoDeviceNotAvailableWithMultipleForegroundApps

Fix: Show appropriate UI message and resume when user exits Split View:

case .videoDeviceNotAvailableWithMultipleForegroundApps:
    showMessage("Camera unavailable in Split View. Use full screen.")

Time to fix: 15 min

Pattern 7: Thermal Pressure

Symptom: Camera stops randomly, especially after prolonged use

Root cause: Device getting hot, system reducing resources

Diagnostic:

// Check thermal state
print("Thermal state: \(ProcessInfo.processInfo.thermalState.rawValue)")
// 0 = nominal, 1 = fair, 2 = serious, 3 = critical

Fix: Reduce quality or show cooling message:

case .videoDeviceNotAvailableDueToSystemPressure:
    // Reduce quality
    session.sessionPreset = .medium
    showMessage("Camera quality reduced due to device temperature")

Time to fix: 20 min

Pattern 8: Preview Rotation Wrong

Symptom: Preview is rotated 90° from expected

Root cause: Not using RotationCoordinator (iOS 17+) or not observing updates

Diagnostic:

print("Preview connection rotation: \(previewLayer.connection?.videoRotationAngle ?? -1)")

Fix:

// Create and observe RotationCoordinator
let coordinator = AVCaptureDevice.RotationCoordinator(device: camera, previewLayer: previewLayer)

// Set initial rotation
previewLayer.connection?.videoRotationAngle = coordinator.videoRotationAngleForHorizonLevelPreview

// Observe changes
observation = coordinator.observe(\.videoRotationAngleForHorizonLevelPreview) { [weak previewLayer] coord, _ in
    DispatchQueue.main.async {
        previewLayer?.connection?.videoRotationAngle = coord.videoRotationAngleForHorizonLevelPreview
    }
}

Time to fix: 30 min

Pattern 9: Captured Photo Rotation Wrong

Symptom: Preview looks correct, but captured photo is rotated

Root cause: Rotation angle not applied to photo output connection

Diagnostic:

if let connection = photoOutput.connection(with: .video) {
    print("Photo connection rotation: \(connection.videoRotationAngle)")
}

Fix:

func capturePhoto() {
    // Apply current rotation to capture
    if let connection = photoOutput.connection(with: .video) {
        connection.videoRotationAngle = rotationCoordinator.videoRotationAngleForHorizonLevelCapture
    }

    photoOutput.capturePhoto(with: settings, delegate: self)
}

Time to fix: 15 min

Pattern 10: Front Camera Mirroring

Symptom: Designer says "front camera photo doesn't match preview"

Reality: This is CORRECT behavior, not a bug.

Explanation:

  • Preview is mirrored (like looking in a mirror - user expectation)
  • Captured photo is NOT mirrored (text reads correctly when shared)
  • This matches the system Camera app behavior

If business requires mirrored photos (selfie apps):

func mirrorImage(_ image: UIImage) -> UIImage? {
    guard let cgImage = image.cgImage else { return nil }
    return UIImage(cgImage: cgImage, scale: image.scale, orientation: .upMirrored)
}

Time to fix: 5 min (explanation) or 15 min (if mirroring required)

Pattern 11: Slow Capture (Quality Priority)

Symptom: Photo capture takes 2+ seconds

Root cause: photoQualityPrioritization =.quality (default for some devices)

Diagnostic:

print("Max quality prioritization: \(photoOutput.maxPhotoQualityPrioritization.rawValue)")
// Check what you're requesting in AVCapturePhotoSettings

Fix:

var settings = AVCapturePhotoSettings()

// For fast capture (social/sharing)
settings.photoQualityPrioritization = .speed

// For balanced (general use)
settings.photoQualityPrioritization = .balanced

// Only use .quality when image quality is critical

Time to fix: 5 min

Pattern 12: Deferred Processing

Symptom: Want maximum responsiveness (zero-shutter-lag)

Solution: Enable deferred processing (iOS 17+)

photoOutput.isAutoDeferredPhotoDeliveryEnabled = true

// Then handle proxy in delegate:
// - didFinishProcessingPhoto gives proxy for immediate display
// - didFinishCapturingDeferredPhotoProxy gives final image later

Time to fix: 30 min

Pattern 13: Permission Not Requested

Symptom: authorizationStatus =.notDetermined

Fix:

// Must request before setting up session
Task {
    let granted = await AVCaptureDevice.requestAccess(for: .video)
    if granted {
        setupSession()
    }
}

Time to fix: 10 min

Pattern 14: Permission Denied

Symptom: authorizationStatus =.denied

Fix: Show settings prompt

func showSettingsPrompt() {
    let alert = UIAlertController(
        title: "Camera Access Required",
        message: "Please enable camera access in Settings to use this feature.",
        preferredStyle: .alert
    )
    alert.addAction(UIAlertAction(title: "Settings", style: .default) { _ in
        if let url = URL(string: UIApplication.openSettingsURLString) {
            UIApplication.shared.open(url)
        }
    })
    alert.addAction(UIAlertAction(title: "Cancel", style: .cancel))
    present(alert, animated: true)
}

Time to fix: 15 min

Pattern 15: API Availability Crash

Symptom: Crash on iOS 16 or earlier

Root cause: Using iOS 17+ APIs without availability check

Fix:

if #available(iOS 17.0, *) {
    // Use RotationCoordinator
    let coordinator = AVCaptureDevice.RotationCoordinator(device: camera, previewLayer: preview)
} else {
    // Fallback to deprecated videoOrientation
    if let connection = previewLayer.connection {
        connection.videoOrientation = .portrait
    }
}

Time to fix: 20 min

Quick Reference Table

SymptomCheck FirstLikely Pattern
Black previewStep 1 (session state)1, 2, or 3
UI freezesStep 2 (threading)4
Freezes on callStep 4 (interruptions)5
Wrong rotationPrint rotation angle8 or 9
Slow capturePrint quality setting11
Denied accessStep 3 (permissions)14
Crash on old iOSCheck @available15

Checklist

Before escalating camera issues:

Basics:

  • ☑ Session has at least one input
  • ☑ Session has at least one output
  • ☑ Session isRunning = true
  • ☑ Preview layer connected to session
  • ☑ Preview layer has non-zero frame

Threading:

  • ☑ All session work on sessionQueue
  • ☑ startRunning() on background thread
  • ☑ UI updates on main thread

Permissions:

  • ☑ Authorization status checked
  • ☑ Permission requested if notDetermined
  • ☑ Graceful UI for denied state

Rotation:

  • ☑ RotationCoordinator created with device AND previewLayer
  • ☑ Observation set up for preview angle changes
  • ☑ Capture angle applied when taking photos

Interruptions:

  • ☑ Interruption observer registered
  • ☑ UI feedback for interrupted state
  • ☑ Tested with incoming phone call

Resources

WWDC: 2021-10247, 2023-10105

Docs: /avfoundation/avcapturesession, /avfoundation/avcapturesessionwasinterruptednotification

Skills: axiom-camera-capture, axiom-camera-capture-ref

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Codex

36.14%
按下载量换算24

Claude

29.87%
按下载量换算20

Cursor

19%
按下载量换算13

Gemini CLI

9.67%
按下载量换算6

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。当前只有一个来源,正式发布前建议补源仓库或其他目录站核验。

来源信息

继续浏览同类 Skills