Setting Up a Capture Session

Horus-iOS·2022년 5월 27일
0

https://developer.apple.com/documentation/avfoundation/cameras_and_media_capture/setting_up_a_capture_session

이 글에 대한 간략한 소개부터 살펴보자.

Configure input devices, output media, preview views, and basic settings before capturing photos or video.

인풋 기기, 아웃풋 미디어, 프리뷰 뷰, 기본적인 세팅을 사진 혹은 비디오 캡처 전에 설정한다는 의미.

Overview

AVCaptureSession이 iOS 및 macOS에서 모든 미디어 캡처에 대한 근본이 된다고 한다. 앱의 운영체제 캡처 인프라 접근 및 기기 접근을 관리한다.

Connect Inputs and Outputs to the Session

인풋과 아웃풋을 세션에 연결할 때 모든 캡처 세션은 적어도 하나의 캡처 인풋과 캡처 아웃풋을 가져야 한다고. 뭐 하나 없으면 나올게 없거나 들어갈게 없는거니까?

AVCaptureDevice로 적합한 기기를 선택, 그리고 그에 상응하는 AVCaptureDeviceInput을 생성.

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)

카메라 기기 선택 방법이 여러 가지인데, 아래 글에서 확인이 가능하다고 한다.

Choosing a Capture Device
https://developer.apple.com/documentation/avfoundation/cameras_and_media_capture/choosing_a_capture_device

전처럼 글을 좀 점잖게 쓸걸 그랬나 싶은데, 이미 시작이 이래버려서 이 글은 그냥 이렇게 쓰기로 했다.

캡처 아웃풋 종류에 따라 달라지는데, 사진이라면 AVCapturePhotoOutput을 세션에 추가해야 한다고. 아웃풋을 세션에 추가하라는 의미.

let photoOutput = AVCapturePhotoOutput()
guard captureSession.canAddOutput(photoOutput) else { return }
captureSession.sessionPreset = .photo
captureSession.addOutput(photoOutput)
captureSession.commitConfiguration()

세션은 다중 인풋 및 아웃풋을 가질 수 있다. 일단 이 글은 무시하도록 한다.

Display a Camera Preview

AVCaptureVideoPreviewLayer를 캡처 세션에 추가해서 세션이 실행될 때마다(running) 카메라로부터 라이브 비디오 피드를 디스플레이하도록 한다. 사용자가 사진을 스냅(?)하는 것을 선택하거나 비디오 레코딩을 시작하기 전에 카메라로부터 인풋을 볼 수 있도록 해주는 것이 중요해서 하라고 한다.

AVCaptureVideoPreviewLayer는 코어 애니메이션 레이어라고 한다. 갑자기 이게 왜 나오는가 싶으면서 무서워지기 시작한다. CALayer 서브클래스로 인터페이스에 표시할 수 있고 스타일링할 수 있다?

UIKit 앱에 프리뷰 레이어를 추가하는 가장 간단한 방법은 UIView를 서브클래스하고, 이 UIVIewlayerClassAVCaptureVideoPreviewLayer인 것을 갖도록. 즉 UIViewlayerClass를 갖는다는 의미.

class PreviewView: UIView {
    override class var layerClass: AnyClass {
        return AVCaptureVideoPreviewLayer.self
    }
    
    /// Convenience wrapper to get layer as its statically known type.
    var videoPreviewLayer: AVCaptureVideoPreviewLayer {
        return layer as! AVCaptureVideoPreviewLayer
    }
}

이후 캡처 세션과 함께 프리뷰 레이어를 사용하려면 레이어의 session 속성을 설정해야 한다고.

self.previewView.videoPreviewLayer.session = self.captureSession

Note
만약 앱이 다중 인터페이스 오리엔테이션을 지원하는 경우 프리뷰 레이어의 connection을 캡처 세션에서 사용해 UI에 맞는 videoOrientation을 설정.

Run the Capture Session

인풋, 아웃풋, 프리뷰를 설정한 후 startRunning()을 호출해서 데이터 흐름이 인풋에서 아웃풋으로 흘러갈 수 있도록 해야한다고 함.

특정 캡처 아웃풋은 세션을 실행(running)하는 것이 미디어 캡처 시작의 전부라고 한다. 예를 들어 세션이 AVCaptureVideoDataOutput을 포함하는 경우 세션이 실행중인 즉시 비디오 프레임 전달을 받는 것을 즉시 시작해야 한다? 세션이 시작되고 레코딩이 바로 들어가야 하기 때문인가?

다른 캡처 아웃풋의 경우 세션 실행을 우선적으로 실행하고, 이후 캡처를 인스턴스화하기 위해 캡처 아웃풋 클래스 자체를 사용하면 된다? 사진 앱을 예시로 말하자면 세션 실행은 뷰파인더 스타일 프리뷰를 가능하게 하면서도, 픽처 스냅을 위해 AVCapturePhotoOutput capturePhoto(with:delegate:) 메소드를 사용하게 될거라고 한다.

0개의 댓글