2017-07-20 15 views
0

SwiftでAVFoundationを使用してビデオを録画する方法を理解しようとしています。私はカスタムカメラを作成する限りは持っていますが、静止画を撮る方法だけを考え出したので、ビデオの記録方法を理解することはできません。あなたが私にこのことを理解させてくれることを願っています。AVFoundation、Swiftでビデオを録画するホールドボタン3

は私がビデオを録画するtakePhotoButtonを保持したいと私は私の現在のスチル写真をプレビューする場所、それがプレビューされます。あなたの助けが本当に私のプロジェクトを続けるのに役立ちます。どうもありがとう!

import UIKit 
import AVFoundation 

@available(iOS 10.0, *) 
class CameraViewController: UIViewController,AVCaptureVideoDataOutputSampleBufferDelegate { 

let photoSettings = AVCapturePhotoSettings() 
    var audioPlayer = AVAudioPlayer() 
    var captureSession = AVCaptureSession() 
    var videoDeviceInput: AVCaptureDeviceInput! 
    var previewLayer = AVCaptureVideoPreviewLayer() 
    var frontCamera: Bool = false 
    var captureDevice:AVCaptureDevice! 
    var takePhoto = false 

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

    override func viewWillAppear(_ animated: Bool) { 
     super.viewWillAppear(animated) 
     prepareCamera() 
    } 

    func prepareCamera() { 
     captureSession.sessionPreset = AVCaptureSessionPresetPhoto 

     if let availableDevices = AVCaptureDeviceDiscoverySession(deviceTypes: [.builtInWideAngleCamera], mediaType: AVMediaTypeVideo, position: .back).devices { 
      captureDevice = availableDevices.first 
      beginSession() 
     } 
    } 

    func frontCamera(_ front: Bool){ 
     let devices = AVCaptureDevice.devices() 

     do{ 
      try captureSession.removeInput(AVCaptureDeviceInput(device:captureDevice!)) 
     }catch{ 
      print("Error") 
     } 

     for device in devices!{ 
      if((device as AnyObject).hasMediaType(AVMediaTypeVideo)){ 
       if front{ 
        if (device as AnyObject).position == AVCaptureDevicePosition.front { 
         captureDevice = device as? AVCaptureDevice 

         do{ 
          try captureSession.addInput(AVCaptureDeviceInput(device: captureDevice!)) 
         }catch{} 
         break 
        } 
       }else{ 
        if (device as AnyObject).position == AVCaptureDevicePosition.back { 
         captureDevice = device as? AVCaptureDevice 

         do{ 
          try captureSession.addInput(AVCaptureDeviceInput(device: captureDevice!)) 
         }catch{} 
         break 
        } 
       } 
      } 
     } 
    } 

    func beginSession() { 
     do { 
      let captureDeviceInput = try AVCaptureDeviceInput(device: captureDevice) 
      if let previewLayer = AVCaptureVideoPreviewLayer(session: captureSession) { 
      self.previewLayer = previewLayer 
      containerView.layer.addSublayer(previewLayer as? CALayer ?? CALayer()) 
      self.previewLayer.frame = self.view.layer.frame 
      self.previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill 
      previewLayer.connection.videoOrientation = AVCaptureVideoOrientation.portrait 
      captureSession.startRunning() 

      let dataOutput = AVCaptureVideoDataOutput() 
      dataOutput.videoSettings = [(kCVPixelBufferPixelFormatTypeKey as NSString):NSNumber(value:kCVPixelFormatType_32BGRA)] 

      dataOutput.alwaysDiscardsLateVideoFrames = true 

      if captureSession.canAddOutput(dataOutput) { 
       captureSession.addOutput(dataOutput) 

       photoSettings.isHighResolutionPhotoEnabled = true 
       photoSettings.isAutoStillImageStabilizationEnabled = true 
      } 

      captureSession.commitConfiguration() 

      let queue = DispatchQueue(label: "com.NightOut.captureQueue") 
      dataOutput.setSampleBufferDelegate(self, queue: queue) 
     } 
    } 
     @IBAction func takePhoto(_ sender: Any) { 
      takePhoto = true 

      photoSettings.isHighResolutionPhotoEnabled = true 
      photoSettings.isAutoStillImageStabilizationEnabled = true 
    } 

    func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!) { 
     if takePhoto { 
      takePhoto = false 
      if let image = self.getImageFromSampleBuffer(buffer: sampleBuffer) { 
       let photoVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "PhotoVC") as! PhotoPreviewViewController 

       photoVC.takenPhoto = image 

       DispatchQueue.main.async { 
        self.present(photoVC, animated: true, completion: { 
         self.stopCaptureSession() 
        }) 
       } 
      } 
     } 
    } 

    func getImageFromSampleBuffer (buffer:CMSampleBuffer) -> UIImage? { 
     if let pixelBuffer = CMSampleBufferGetImageBuffer(buffer) { 
      let ciImage = CIImage(cvPixelBuffer: pixelBuffer) 
      let context = CIContext() 

      let imageRect = CGRect(x: 0, y: 0, width: CVPixelBufferGetWidth(pixelBuffer), height: CVPixelBufferGetHeight(pixelBuffer)) 

      if let image = context.createCGImage(ciImage, from: imageRect) { 
       return UIImage(cgImage: image, scale: UIScreen.main.scale, orientation: .leftMirrored) 
      } 
    } 
     return nil 
    } 

    override func viewWillDisappear(_ animated: Bool) { 
     super.viewWillDisappear(animated) 

     self.captureSession.stopRunning() 
    } 

    func stopCaptureSession() { 
     self.captureSession.stopRunning() 

     if let inputs = captureSession.inputs as? [AVCaptureDeviceInput] { 
      for input in inputs { 
       self.captureSession.removeInput(input) 
      } 
     } 
    } 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
    } 

    @IBAction func DismissButtonAction(_ sender: UIButton) { 

     UIView.animate(withDuration: 0.1, animations: { 
      self.DismissButton.transform = CGAffineTransform.identity.scaledBy(x: 0.8, y: 0.8) 
     }, completion: { (finish) in 
      UIView.animate(withDuration: 0.1, animations: { 
       self.DismissButton.transform = CGAffineTransform.identity 
      }) 
     }) 
     performSegue(withIdentifier: "Segue", sender: nil) 
    } 
} 

答えて

0

あなたがAVCaptureMovieFileOutputを使用する必要があります。録音

あなたは startRecording(to:recordingDelegate:)を使用して、QuickTimeムービーの記録を開始する開始addOutput(_:)

使用してキャプチャセッションにAVCaptureMovieFileOutputを追加します。 ファイルベースのURLとデリゲートを提供する必要があります。 URLは、既存の ファイルを識別してはいけません。これは、ムービーファイル出力が既存の リソースを上書きしないためです。指定した の場所に書き込む権限も必要です。デリゲートは AVCaptureFileOutputRecordingDelegateプロトコルに準拠している必要があり、 fileOutput(_:didFinishRecordingTo:from:error:) メソッドを実装する必要があります。

詳細はdocsを参照してください。

+0

の記録を停止する

let videoFileOutput = AVCaptureMovieFileOutput() self.captureSession?.addOutput(videoFileOutput) let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] as URL let filePath = documentsURL.appendingPathComponent("tempMovie") videoFileOutput.startRecording(toOutputFileURL: filePath, recordingDelegate: self) 

の記録を開始するHoldDown()メソッドの内部で、このコードをお持ちですか?ありがとう – RandomGeek

2

ボタンを押したままにして放すことを確認するには、さまざまな方法があります。最も簡単な方法は、以下のようにキャプチャボタンにUIControlEvents.TouchUpInsideUIControlEvents.TouchDownのターゲットを追加することです。

aButton.addTarget(self, action: Selector("holdRelease:"), forControlEvents: UIControlEvents.TouchUpInside); 
aButton.addTarget(self, action: Selector("HoldDown:"), forControlEvents: UIControlEvents.TouchDown) 

//target functions 
func HoldDown(sender:UIButton) 
{ 
     // Start recording the video 
} 

func holdRelease(sender:UIButton) 
{ 
     // Stop recording the video 
} 

ボタンやビューに長いタップジェスチャ認識機能を追加し、認識機能の状態に基づいて開始/停止するなどの方法もあります。詳細情報はこちら他に見出すことができSO UIButton with hold down action and release action

ビデオ録画

答えるあなたのキャプチャセッションにAVCaptureMovieFileOutputを追加して、ビデオ録画を開始する方法startRecordingToOutputFileURLを使用する必要があります。

  • ファイルパスを記録開始とdidFinishを識別するためにAVCaptureFileOutputRecordingDelegateメソッドを実装し、注意すべき

    物事はあなたがあなたのアプリがアクセス権を持って正しいファイルパスを与える必要があります意味する有意義にする必要があります。あなたは多分私の既存のコードにこれを追加助けてもらえ

は使用vidoeFileOutput.stopRecording()

+0

これは非常に詳細で美しい答えですが、コードスニペットで私を助けてくれますか?私はデリゲートを実装する方法を理解していなかったし、リンゴのドキュメントは役に立たなかった/私はそれらを理解していませんでした。まだよく学習しています。ありがとう – RandomGeek

+0

@RandomGeek私はGithubのSwiftカメラコードをベースにしました。私は最近レコードビデオ機能を追加しました。録画ビデオを実装して再生する方法の詳細については、このGithub [repo branch](https://github.com/rizwankce/Camera/tree/feature/record-video)をご覧ください。これが助けて欲しいです – Bluewings

+0

ありがとう:)私はそれを調べます。 – RandomGeek

関連する問題