2017-12-26 21 views
1

カスタムカメラを作成しましたが、ビデオの録画中に前面と背面のカメラを切り替えることができる機能を追加しようとしています。今私のアプローチは、カメラを切り替えるときに新しいビデオを停止して開始することですが、ビデオを少しだけ切り詰めてしまいます。理由はわかりません。どのようにスナップショットのようにすることができるので、完全なビデオを取得し、カメラを切り替えるときに何かをカットしません。ここで私はあなたの質問に答えるだろうと思い、これまでビデオの録画中に前面と背面のカメラを切り替える

@objc func switchCameraInput() { 
     self.captureSession.beginConfiguration() 
     var existingConnection:AVCaptureDeviceInput! 

     for connection in self.captureSession.inputs { 
      let input = connection as! AVCaptureDeviceInput 
      if input.device.hasMediaType(AVMediaType.video) { 
       existingConnection = input 
      } 
     } 

     self.captureSession.removeInput(existingConnection) 
     turnFlashOff() 

     var newCamera:AVCaptureDevice! 
     if let oldCamera = existingConnection { 
      if oldCamera.device.position == .back { 
       newCamera = self.cameraWithPosition(position: .front) 
      } else { 
       newCamera = self.cameraWithPosition(position: .back) 
      } 
     } 

     var newInput:AVCaptureDeviceInput! 

     do { 
      newInput = try AVCaptureDeviceInput(device: newCamera) 
      self.captureSession.addInput(newInput) 

     } catch { 
      ProgressHUD.showError(error.localizedDescription) 
     } 


     self.captureSession.commitConfiguration() 

    // This is where i handle switching while recording 
    if self.movieFileOutput.isRecording { 
     hasSwappedCamera = true 
     turnFlashOff() 
     //self.movieFileOutput.stopRecording() 
     self.movieFileOutput.connection(with: AVMediaType.video)?.videoOrientation = self.videoOrientation() 
     self.movieFileOutput.maxRecordedDuration = self.maxRecordedDuration() 
     self.movieFileOutput.startRecording(to: URL(fileURLWithPath:self.videoFileLocation()), recordingDelegate: self) 
     turnOnFlash() 
    } 
} 
+0

この質問のように見えるかもしれません... https://stackoverflow.com/questions/44577331/multiple-avcapturevideodataoutput-in-same-avcapturesession – BHendricks

+0

@BHendricksこれは客観的なCで、あなたが私を助けてくれるチャンスです迅速に? – vApp

答えて

0

the questionので、私のコードは、Objective-Cでされている、あなたは、私はすべてそのコード以下の「翻訳」しましスウィフトを好むだろう。

私はこれをコンパイルしていないので、いくつかのことをコンパイルできないことを知っておいてください。 AVMediaTypeVideoのような列挙値は通常Swiftの.videoです。また、答えにはいくつかの間違ったコードがあり、主にisFrontRecordingisBackRecordingブール値をfalseに設定していることを確認しています。私はそれらがcompletionHandlerの中で起こるべきだと思いますが、言及したように私はこれをコンパイルしなかったので、塩の穀物でそれを取る。私はその質問(Objective-C)のすべてのコードをSwiftへの私の速い&汚い翻訳と一緒に含めました。私はこれが役に立てば幸い

、:)

のObjective-Cかかわら:

/* Front camera settings */ 
@property bool isFrontRecording; 
@property (strong, nonatomic) AVCaptureDeviceInput *videoInputBack; 
@property (strong, nonatomic) AVCaptureStillImageOutput *imageOutputBack; 
@property (strong, nonatomic) AVCaptureSession *sessionBack; 

/* Back camera settings */ 
@property bool isBackRecording; 
@property (strong, nonatomic) AVCaptureDeviceInput *videoInputFront; 
@property (strong, nonatomic) AVCaptureStillImageOutput *imageOutputFront; 
@property (strong, nonatomic) AVCaptureSession *sessionFront; 

スウィフト:

var isFrontRecording: Bool 
var videoInputBack: AVCaptureDeviceInput 
var imageOutputBack: AVCaptureStillImageOutput 
var sessionBack: AVCaptureSession 

var isBackRecording: Bool 
var videoInputFront: AVCaptureDeviceInput 
var imageOutputFront: AVCaptureStillImageOutput 
var sessionFront: AVCaptureSession 

のObjective-C

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    [self setupBackAVCapture]; 

    self.isFrontRecording = NO; 
    self.isBackRecording = NO; 
} 

- (void)setupBackAVCapture 
{ 
    NSError *error = nil; 

    self.sessionBack = [[AVCaptureSession alloc] init]; 
    self.sessionBack.sessionPreset = AVCaptureSessionPresetPhoto; 

    AVCaptureDevice *camera = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; 

    self.videoInputBack = [[AVCaptureDeviceInput alloc] initWithDevice:camera error:&error]; 
    [self.sessionBack addInput:self.videoInputBack]; 

    self.imageOutputBack = [[AVCaptureStillImageOutput alloc] init]; 
    [self.sessionBack addOutput:self.imageOutputBack]; 

} 

スウィフト:

override func viewDidLoad() { 
    super.viewDidLoad() 
    setupBackAVCapture() 

    isFrontRecording = false 
    isBackRecording = false 
} 

func setupBackAVCapture() { 
    var error: NSError = nil 
    sessionBack = AVCaptureSession() 
    sessionBack.sessionPreset = AVCaptureSessionPresetPhoto 

    let camera: AVCaptureDevice = AVCaptureDevice(defaultDeviceWithMediaType: AVMediaTypeVideo) 
    videoInputBack = AVCaptureDeviceInput(withDevice: camera, error: error) 
    sessionBack.addInput(videoInputBack) 

    imageOutputBack = AVCaptureStillImageOutput() 
    sessionBack.addOutput(imageOutputBack) 
} 

のObjective-C:

- (IBAction)buttonCapture:(id)sender { 
    [self takeBackPhoto]; 
} 

- (void)takeBackPhoto 
{ 
    [self.sessionBack startRunning]; 
    if (!self.isFrontRecording) { 

     self.isFrontRecording = YES; 

     AudioServicesPlaySystemSound(kSystemSoundID_Vibrate); 
     AVCaptureConnection *videoConnection = [self.imageOutputBack connectionWithMediaType:AVMediaTypeVideo]; 

     if (videoConnection == nil) { 
      return; 
     } 


     [self.imageOutputBack 
     captureStillImageAsynchronouslyFromConnection:videoConnection 
     completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) { 

      if (imageDataSampleBuffer == NULL) { 
       return; 
      } 

      NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer]; 

      UIImage *image = [[UIImage alloc] initWithData:imageData]; 

      UIImageWriteToSavedPhotosAlbum(image, self, nil, nil); 

      [self.imageView setImage:image]; 

      [self.sessionBack stopRunning]; 

      // Set up front camera setting and capture photo. 
      [self setupFrontAVCapture]; 
      [self takeFrontPhoto]; 

     }]; 

     self.isFrontRecording = NO; 
    } 
} 

スウィフト:

@IBOutlet func buttonCapture(sender: Any) { 
    takeBackPhoto() 
} 

func takeBackPhoto() { 
    sessionBack.startRunning() 
    if !isFrontRecording { 
     isFrontRecording = true 

     AudioServicesPlaySystemSound(kSystemSoundID_Vibrate) 
     let videoConnection: AVCaptureConnection = imageOutputBack.connectionWithMediaType(AVMediaTypeVideo) 

     guard let videoConnection = videoConnection else { 
      return 
     } 

     imageOutputBack.captureStillImageAsynchronouslyFromConnection(videoConnection, completionHandler: { 
      imageDataSampleBuffer: CMSSampleBufferRef, error: NSError in 

      guard let imageDataSampleBuffer = imageDataSampleBuffer else { 
       return 
      } 

      let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(imageDataSampleBuffer) 
      let image = UIImage(data: imageData) 
      UIImageWriteToSavedPhotosAlbum(image, self, nil, nil) 
      self.imageView.setImage(image) 
      self.sessionback.stopRunning() 

      // Set up front camera setting and capture photo. 
      self.setupFronAVCapture() 
      self.takeFrontPhoto() 
     }) 

     isFrontRecording = false 
    } 
} 

のObjective-C

- (void)setupFrontAVCapture 
{ 
    NSError *error = nil; 

    self.sessionFront = [[AVCaptureSession alloc] init]; 
    self.sessionFront.sessionPreset = AVCaptureSessionPresetPhoto; 

    AVCaptureDevice *camera = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; 
    camera = [self cameraWithPosition:AVCaptureDevicePositionFront]; 

    self.videoInputFront = [[AVCaptureDeviceInput alloc] initWithDevice:camera error:&error]; 
    [self.sessionFront addInput:self.videoInputFront]; 

    self.imageOutputFront = [[AVCaptureStillImageOutput alloc] init]; 
    [self.sessionFront addOutput:self.imageOutputFront]; 
} 

- (void)takeFrontPhoto 
{ 
    [self.sessionFront startRunning]; 
    if (!self.isBackRecording) { 

     self.isBackRecording = YES; 

     AudioServicesPlaySystemSound(kSystemSoundID_Vibrate); 
     AVCaptureConnection *videoConnection = [self.imageOutputFront connectionWithMediaType:AVMediaTypeVideo]; 

     if (videoConnection == nil) { 
      return; 
     } 


     [self.imageOutputFront 
     captureStillImageAsynchronouslyFromConnection:videoConnection 
     completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) { 

      if (imageDataSampleBuffer == NULL) { 
       return; 
      } 

      NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer]; 

      UIImage *image = [[UIImage alloc] initWithData:imageData]; 

      UIImageWriteToSavedPhotosAlbum(image, self, nil, nil); 
      [self.imageViewBack setImage:image]; 

      [self.sessionFront stopRunning]; 


     }]; 

     self.isBackRecording = NO; 

    } 

} 

スウィフト:

あなたのプロジェクトのために切り替えがうまくいっていることを祈ってください!

関連する問題