2017-12-05 21 views
0

비디오 입력을 캡처해야하지만 화면에 표시하지 않아야하는 Swift 기반 MacOS 응용 프로그램에서 작업 중입니다 ... 비디오를 표시하는 대신 버퍼링 된 데이터를 다른 곳에서 처리하고 결국 SceneKit 장면의 객체에 표시합니다.미리보기 창없이 AVCaptureVideoDataOutputSampleBufferDelegate 사용하기

fileprivate func startSession() { 
    if let videoSession = videoSession { 
     if !videoSession.isRunning { 
      self.videoInputRunning = true 
      videoSession.startRunning() 
     } 
    } 
} 

나는 또한 내가 캡처하려는 AVCaptureVideoDataOutputSampleBufferDelegate를 구현 다음 AVCaptureSession 세션을 시작

fileprivate func prepareCamera() { 
     self.videoSession = AVCaptureSession() 
     self.videoSession.sessionPreset = AVCaptureSession.Preset.photo 

     if let devices = AVCaptureDevice.devices() as? [AVCaptureDevice] { 
      for device in devices { 
       if device.hasMediaType(AVMediaType.video) { 
        cameraDevice = device 

        if cameraDevice != nil { 
         do { 
          let input = try AVCaptureDeviceInput(device: cameraDevice) 


          if videoSession.canAddInput(input) { 
           videoSession.addInput(input) 
          } 


          } catch { 
          print(error.localizedDescription) 
         } 
        } 
       } 
      } 

      let videoOutput = AVCaptureVideoDataOutput() 
      videoOutput.setSampleBufferDelegate(self as AVCaptureVideoDataOutputSampleBufferDelegate, queue: DispatchQueue(label: "sample buffer delegate", attributes: [])) 
      if videoSession.canAddOutput(videoOutput) { 
       videoSession.addOutput(videoOutput) 
      } 
     } 
    } 

그리고 startSession 방법 :

은 내가 prepareCamera 방법이있는 CameraInput 클래스가 CMSampleBuffer 나중에 사용하기 :

extension CameraInput: AVCaptureVideoDataOutputSampleBufferDelegate { 

    internal func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!) { 
     print(Date()) 
    } 
} 

그러나 위임은 결코 호출되지 않습니다. 이 상황이 내가 일 때이 표시되도록 비디오 출력을 표시 할 수 있습니까?

+0

이 클래스의 코드를 작성할 때 어떤 수업을 듣고 있습니까? 입력 장치가 무엇입니까? –

+0

@ElTomato 입력 장치는 내 맥의 직관 형 카메라입니다. 이 클래스는 NSObject에서 상속받은 CameraInput이라는 사용자 정의 클래스입니다. – narner

+0

previewLayer를 사용하고 있지 않습니다. 그것은 무엇을위한 것인가? 내 지식에, 너는 그것을 필요로한다. –

답변

1

캡처 한 비디오의 미리보기를 표시할지 여부와 관련하여 문제가 없습니다. 당신은 스위프트 사에있어 (그리고 당신이 것 같습니다) 경우

, 당신은 구현하기 위해 찾고있는 대리자 메서드 서명이 captureOutput(_:didOutputSampleBuffer:from:)하지, 그것은 this입니다 :

optional func captureOutput(_ output: AVCaptureOutput, 
       didOutput sampleBuffer: CMSampleBuffer, 
        from connection: AVCaptureConnection) 

관련없는 팁 :

  • 네임 스페이스 상수는 당신이 좋아하는 경우에 더 짧아 질 수 있음을 의미; 예 : videoSession.sessionPreset = .photo

  • AVCaptureDevice.devices()은 더 이상 사용되지 않습니다. 대신 ask AVCaptureDevice for exactly the kind of device you want, 자신을 그를 호출 장치를 통해 루핑의 : 클래스가 이미 AVCaptureVideoDataOutputSampleBufferDelegate 프로토콜 준수를 선언하는 경우

    let captureDevice = AVCaptureDevice.default(.builtInWideAngleCamera, 
                 for: .video, position: .back) 
    
  • 당신은 videoOutput.setSampleBufferDelegate(self as AVCaptureVideoDataOutputSampleBufferDelegate에서 as 캐스트가 필요하지 않습니다. 당신은 단지 SceneKit 장면의 일부에 매핑 라이브하여 카메라에서 영상을 얻기 위해 찾고 있다면


마지막으로, 즉 아이폰 OS 11에서 당신이 SCNMaterialProperty '에 AVCaptureDevice을 할당 할 수 있습니다 s contents - 직접 픽셀 버퍼를 잡아서 처리하고 이동할 필요가 없습니다.

+0

훌륭해, 고마워! – narner