본문 바로가기
Apple의 SDK/AVFoundation

[AVFoundation/capture] 캡쳐 설정하기

by lody.park 2024. 12. 7.

⭐️ 카메라 기능을 사용하기 위해서는 권한 설정을 필수로 해야한다 

 

캡쳐 세션 (AVCaptureSession)

앱이 카메라와 마이크 같이 기기를 이용해 사진, 동영상을 찍거나 녹화할 수 있도록 해주는 가장 기본이 되는 시스템임.

세션은 입력 장치에서 출력 장치데이터를 연결해 전달하는 역할임.

✅ 투두리스트
1) 캡쳐 세션을 만들고 입력과 출력 설정
2) 미리보기 UI를 구성
3) 세션의 데이터 흐름 관리하기

입력과 출력을 세션에 연결하기

모든 캡쳐 세션에는 적어도 하나 이상의 캡쳐 입력캡쳐 출력이 필요함.

  • 캡쳐 입력(AVCaptureInput 하위 클래스): 일반적으로 iOS 기기나 Mac에 내장된 카메라와 마이크와 같은 미디어 소스
  • 캡쳐 출력(AVCaptureOutput 하위 클래스): 캡쳐 입력에서 제공하는 데이터를 사용하여 이미지나 동영상 파일과 같은 미디어를 생성

⭐️ 세션의 입력이나 출력을 변경할때 아래 메서드를 반드시 호출해야한다.

  • 변경 전, beginConfiguration() 호출
  • 변경 후, commitConfiguration() 호출

 

1. 캡쳐 세션 만들기

캡쳐 세션은 입력(AVCaptureInput)을 addInput(AVCaptureInput:) 으로 연결할 수 있다.

캡쳐 세션은 출력(AVCaptureOutput)을 addOutput(AVCaptureOutput:) 으로 연결할 수 있다. 

 

2. 세션에 입력 설정하기 - 카메라를 사용하여 비디오 입력(사진 또는 동영상 캡쳐)을 수행하기

  1. 적절한 장치(AVCaptureDevice)를 선택 
  2. 해당 장치에 대한 AVCaptureDeviceInput 생성
  3. 이를 캡쳐 세션에 추가하기
captureSession.beginConfiguration() // ⭐️ 세션 변경 전, 필수 작업
let videoDevice = AVCaptureDevice.default(.builtInWideAngleCamera,
                                          for: .video, position: .unspecified)
guard
    let videoDeviceInput = try? AVCaptureDeviceInput(device: videoDevice!),
    captureSession.canAddInput(videoDeviceInput)
    else { return }
captureSession.addInput(videoDeviceInput)

 

3. 세션에 출력 설정하기

선택한 카메라에서 캡쳐하려는 미디어 유형에 맞는 출력을 세션에 추가한다.

사진 캡쳐를 활성화 하려면 AVCapturePhotoOutput을 세션에 추가한다.

  1. AVCapturePhotoOutput 생성
  2. 이를 캡쳐 세션에 추가하기
let photoOutput = AVCapturePhotoOutput()
guard captureSession.canAddOutput(photoOutput) else { return }
captureSession.sessionPreset = .photo
captureSession.addOutput(photoOutput)
captureSession.commitConfiguration() // ⭐️ 세션 변경 후, 커밋 반드시 필요

 

 

 

(+) 세션은 여러 입력과 출력을 가질 수 있다. 예를 들어

  • 입력: 동영상과 오디오를 동시에 녹화하려면 카메라와 마이크 장치에 대한 입력을 모두 추가한다.
  • 출력: 동일한 카메라에서 사진과 동영상을 동시에 캡쳐하려면 AVCapturePhotoOutput과 AVCaptureMovieFileOutput을 모두 세션에 추가한다.

 

카메라 Preview 표시하기

AVCaptureVideoPreviewLayer를 이용하면 캡쳐 세션이 실행되는 동안 카메라에서 실시간 비디오 피드를 표시할 수 있음.

 

AVCaptureVideoPreviewLayer

  • CALayer의 서브클래스로 인터페이스에 표시 가능.
  • 캡쳐 세션에 연결

* UIKit으로 하는법

class PreviewView: UIView {
    override class var layerClass: AnyClass {
        return AVCaptureVideoPreviewLayer.self
    }
    
    var videoPreviewLayer: AVCaptureVideoPreviewLayer {
     // ✅ layer는 CALayer 타입. 구체적으로 다운 캐스팅 필요
        return layer as! AVCaptureVideoPreviewLayer
    }
}

// ✅ 캡쳐 세션 연결 to AVCaptureVideoPreviewLayer
self.previewView.videoPreviewLayer.session = self.captureSession

 

 

⭐️ 앱이 여러 인터페이스 방향(orientation)을 지원하는 경우,

프리뷰 레이어의 connection을 사용하여 UI와 일치하는 videoOrientation(iOS 4.0 ~ 17.0, Deprecated) 또는 videoRotationAngle(iOS 17.0+) 을 설정 

 

캡쳐 세션 실행하기

세션 설정(입출력). 프리뷰 설정을 마쳤다면,

입력에서 출력으로 데이터가 흐를 수 있도록 startRunning()을 호출.

 

captureSession.startRunning()
// AVCaptureVideoDataOutput이 포함된 경우, 실행 즉시 비디오 프레임이 전달.

 

일부 캡처 출력의 경우, 세션을 실행하는 것만으로 미디어 캡처를 시작할 수 있음.

예를 들어, 세션에 AVCaptureVideoDataOutput이 포함되어 있다면, 세션이 실행되는 즉시 비디오 프레임을 전달받기 시작함.

 

다른 캡처 출력의 경우, 세션 실행 이후 캡처 출력을 직접 호출하여 캡처를 시작해야 함.

예를 들어, 사진 앱에서는 세션을 실행하면 뷰파인더 스타일의 프리뷰가 활성화되지만,

사진 촬영을 위해서는 AVCapturePhotoOutputcapturePhoto(with:delegate:) 메서드를 호출해야 함.