1

OSX 앱에 두 개의 카메라 피드가 있고 AVCaptureMovieFileOutput을 사용하여 카메라 피드를 저장하려고합니다. 동영상이 동기화되지 않아 오래 걸리지는 않습니다. 최소 테스트 후 1 ~ 5 초 정도 벗어날 수 있습니다. 1 시간 후에 그들은 20 대가됩니다. 두 출력을 동기화하는 일종의 간단한 해결책이 있어야한다고 생각합니다. 우리는 세션과 출력 모두에 대해 동일한 장치를 사용해 보았으며 동일한 문제가 발생합니다. 우리는 fps를 15 이하로 강요했지만 여전히 운이 없었습니다. 정확한 타이밍 제어를 위해두 개의 AVCaptureMovieFileOutput을 동기화 상태로 유지하는 방법

설정 출력

func assignDeviceToPreview(captureSession: AVCaptureSession, device: AVCaptureDevice, previewView: NSView, index: Int){ 

    captureSession.stopRunning() 

    captureSession.beginConfiguration() 

    //clearing out old inputs 
    for input in captureSession.inputs { 
     let i = input as! AVCaptureInput 
     captureSession.removeInput(i) 
    } 

    let output = self.outputs[index] 
    output.outputSettings = [AVVideoCodecKey: AVVideoCodecJPEG] 

    //removing old outputs 
    for o in captureSession.outputs{ 
     if let oc = o as? AVCaptureStillImageOutput{ 
      captureSession.removeOutput(oc) 
      print("removed image out") 
     } 
    } 

    //Adding input 
    do { 

     try captureSession.addInput(AVCaptureDeviceInput(device:device)) 

     let camViewLayer = previewView.layer! 
     camViewLayer.backgroundColor = CGColorGetConstantColor(kCGColorBlack) 

     let previewLayer = AVCaptureVideoPreviewLayer(session: captureSession) 
     previewLayer.frame = camViewLayer.bounds 
     previewLayer.autoresizingMask = [.LayerWidthSizable, .LayerHeightSizable] 

     camViewLayer.addSublayer(previewLayer) 

     let overlayPreview = overlayPreviews[index] 
     overlayPreview.frame.origin = CGPoint.zero 

     previewView.addSubview(overlayPreview) 

     //adding output 
     captureSession.addOutput(output) 

     if captureSession == session2{ 
      let audio = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeAudio) 

      do { 
       let input = try AVCaptureDeviceInput(device: audio) 
       captureSession.addInput(input) 
      } 
     } 

    } catch { 
     print("Failed to add webcam as AV input") 
    } 

    captureSession.commitConfiguration() 
    captureSession.startRunning() 
} 

기록 시작은

func startRecording(){ 

    startRecordingTimer() 

    let base = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] 
    let appFolder = "Sessions" 
    let sessionFolder = "session_" + session.UUID 

    let path = base+"/"+appFolder+"/"+sessionFolder 

    do{ 
     try NSFileManager.defaultManager().createDirectoryAtPath(path, withIntermediateDirectories: true, attributes: nil) 
    }catch{ 
     print("issue creating folder") 
    } 

    for fileOutput in fileOutputs{ 

     let fileName = "cam\(String(fileOutputs.indexOf(fileOutput)!))" + ".mov" 

     let fileURL = NSURL.fileURLWithPathComponents([path, fileName]) 
     fileURLs.append(fileURL!) 
     print(fileURL?.absoluteString) 

     var captureConnection = fileOutput.connections.first as? AVCaptureConnection 
     captureConnection!.videoMinFrameDuration = CMTimeMake(1, 15) 
     captureConnection!.videoMaxFrameDuration = CMTimeMake(1, 15) 

     if fileOutput == movieFileOutput1{ 
      fileOutput.setOutputSettings([AVVideoScalingModeKey: AVVideoScalingModeResize, AVVideoCodecKey: AVVideoCodecH264, AVVideoWidthKey: 1280, AVVideoHeightKey: 720], forConnection: captureConnection) 
     }else{ 
      fileOutput.setOutputSettings([AVVideoScalingModeKey: AVVideoScalingModeResizeAspect, AVVideoCodecKey: AVVideoCodecH264, AVVideoWidthKey: 640, AVVideoHeightKey: 360], forConnection: captureConnection) 
     } 
     captureConnection = fileOutput.connections.first as? AVCaptureConnection 
     print(fileOutput.outputSettingsForConnection(captureConnection)) 

     fileOutput.startRecordingToOutputFileURL(fileURL, recordingDelegate: self) 

     print("start recording") 
    } 

} 

답변

2

, 난 당신이 낮은 수준의 AVAssetWriter 프레임 워크를 사용하여 조사해야합니다 생각합니다. 이를 통해 개별 프레임의 기록 및 타이밍을 제어 할 수 있습니다.

AVAssetWriter.startSession (atSourceTime : CMTime)을 사용하면 각 카메라에서 녹화가 시작될 때 정확하게 제어 할 수 있습니다.

AVCaptureVideoDataOutputSampleBufferDelegate를 사용하는 쓰기 프로세스 중에 생성 된 CMSampleBuffer를 더 조작하여 타이밍 정보를 조정하고 두 비디오를 계속 동기화 할 수 있습니다. CMSampleBuffer의 타이밍 부분 조정에 대한 참조는 https://developer.apple.com/reference/coremedia/1669345-cmsamplebuffer을 참조하십시오.

그렇긴하지만 나는 이것을 시도한 적이 없으며 이것이 효과가 있을지 확실하지 않지만이 길로 가면 얻을 수있는 목표에 근접 할 것이라고 확신합니다.

+0

감사합니다. 나는 이것을 들여다 볼 것입니다. –

+1

정말 고마워요. Googleing과 시행 착오를 많이 겪었지만 개별 프레임을 작성하고 버퍼가 올바른 것으로 생각하는 대신 실시간으로 계산을 기반으로 수동 제어가 가능한 시점까지 도달했습니다. 두 동영상 모두 1 시간 23 분 58 초 이제 오디오 부분을 알아 내려고합니다. –

+0

위대한, 기쁜 그게 도움이! –

관련 문제