2016-09-10 2 views
9

안녕하세요 저는 Jared Davidson의 과정을 따라 맞춤 카메라 뷰를 만들고 AVFoundation을 사용하여 사진을 저장했습니다. https://www.youtube.com/watch?v=w0O3ZGUS3pkAVFoundation 스위프트를 사용하여 비디오 저장

그러나 이미지 대신 동영상을 녹화하고 저장하고 싶습니다. 누군가 나를 도와 줄 수 있습니까? 나는 그 단순하지만 애플의 문서가 Objective-C로 쓰여졌 고 그것을 해독 할 수 없다고 확신한다.

이것은 내 코드입니다. 감사.

import UIKit 
import AVFoundation 

class ViewController: UIViewController { 

    var captureSession = AVCaptureSession() 
    var sessionOutput = AVCaptureStillImageOutput() 
    var previewLayer = AVCaptureVideoPreviewLayer() 


    @IBOutlet var cameraView: UIView! 

    override func viewWillAppear(animated: Bool) { 

     let devices = AVCaptureDevice.devicesWithMediaType(AVMediaTypeVideo) 
     for device in devices { 
      if device.position == AVCaptureDevicePosition.Front{ 


       do{ 

        let input = try AVCaptureDeviceInput(device: device as! AVCaptureDevice) 

        if captureSession.canAddInput(input){ 

         captureSession.addInput(input) 
         sessionOutput.outputSettings = [AVVideoCodecKey : AVVideoCodecJPEG] 

         if captureSession.canAddOutput(sessionOutput){ 

          captureSession.addOutput(sessionOutput) 
          captureSession.startRunning() 

          previewLayer = AVCaptureVideoPreviewLayer(session: captureSession) 
          previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill 
          previewLayer.connection.videoOrientation = AVCaptureVideoOrientation.Portrait 
          cameraView.layer.addSublayer(previewLayer) 

          previewLayer.position = CGPoint(x: self.cameraView.frame.width/2, y: self.cameraView.frame.height/2) 
          previewLayer.bounds = cameraView.frame 


         } 

        } 

       } 
       catch{ 

        print("Error") 
       } 

      } 
     }  

    } 


    @IBAction func TakePhoto(sender: AnyObject) { 

     if let videoConnection = sessionOutput.connectionWithMediaType(AVMediaTypeVideo){ 

      sessionOutput.captureStillImageAsynchronouslyFromConnection(videoConnection, completionHandler: { 
       buffer, error in 

       let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(buffer) 
       UIImageWriteToSavedPhotosAlbum(UIImage(data: imageData)!, nil, nil, nil) 

      }) 

     } 

    } 

} 

답변

15

당신은 만들고 캡처 세션에 AVCaptureMovieFileOutput를 추가하고 ViewControllerAVCaptureFileOutputRecordingDelegate을 준수하여 파일로 동영상을 녹화 저장할 수 있습니다.

이 예제는 5 초의 비디오를 응용 프로그램의 Documents 디렉토리에있는 "output.mov"라는 파일에 기록합니다.

class ViewController: UIViewController, AVCaptureFileOutputRecordingDelegate { 

    var captureSession = AVCaptureSession() 
    var sessionOutput = AVCaptureStillImageOutput() 
    var movieOutput = AVCaptureMovieFileOutput() 
    var previewLayer = AVCaptureVideoPreviewLayer() 

    @IBOutlet var cameraView: UIView! 

    override func viewWillAppear(animated: Bool) { 
     self.cameraView = self.view 

     let devices = AVCaptureDevice.devicesWithMediaType(AVMediaTypeVideo) 
     for device in devices { 
      if device.position == AVCaptureDevicePosition.Front{ 


       do{ 

        let input = try AVCaptureDeviceInput(device: device as! AVCaptureDevice) 

        if captureSession.canAddInput(input){ 

         captureSession.addInput(input) 
         sessionOutput.outputSettings = [AVVideoCodecKey : AVVideoCodecJPEG] 

         if captureSession.canAddOutput(sessionOutput){ 

          captureSession.addOutput(sessionOutput) 

          previewLayer = AVCaptureVideoPreviewLayer(session: captureSession) 
          previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill 
          previewLayer.connection.videoOrientation = AVCaptureVideoOrientation.Portrait 
          cameraView.layer.addSublayer(previewLayer) 

          previewLayer.position = CGPoint(x: self.cameraView.frame.width/2, y: self.cameraView.frame.height/2) 
          previewLayer.bounds = cameraView.frame 


         } 

         captureSession.addOutput(movieOutput) 

         captureSession.startRunning() 

         let paths = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask) 
         let fileUrl = paths[0].URLByAppendingPathComponent("output.mov") 
         try? NSFileManager.defaultManager().removeItemAtURL(fileUrl) 
         movieOutput.startRecordingToOutputFileURL(fileUrl, recordingDelegate: self) 

         let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(5 * Double(NSEC_PER_SEC))) 
         dispatch_after(delayTime, dispatch_get_main_queue()) { 
          print("stopping") 
          self.movieOutput.stopRecording() 
         } 
        } 

       } 
       catch{ 

        print("Error") 
       } 

      } 
     } 

    } 

    func captureOutput(captureOutput: AVCaptureFileOutput!, didFinishRecordingToOutputFileAtURL outputFileURL: NSURL!, fromConnections connections: [AnyObject]!, error: NSError!) { 
     print("FINISHED \(error)") 
     // save video to camera roll 
     if error == nil { 
      UISaveVideoAtPathToSavedPhotosAlbum(outputFileURL.path!, nil, nil, nil) 
     } 
    } 

} 
+0

Xcode> 기기> iPhone> _app 이름 _> 컨테이너 다운로드의 기기에서 문서 디렉토리를 다운로드 할 수 있습니다. 'didFinishRecordingToOutputFileAtURL' 델리게이트 메소드에서'UISaveVideoAtPathToSavedPhotosAlbum()'을 호출하여 비디오를 카메라 롤에 저장할 수 있습니다. 질문에 대한 답변이 있으면이 대답을 수락하십시오. –

+1

하하 많이 감사합니다! 다행스럽게도 많은 사람들이 물어 보았 기 때문에 다른 사람들에게도 도움이되기를 바랍니다. –

5

고맙습니다. 그것은 나에게 매우 도움이되었다. 다음은 Swift 3에 이식 된 Rhythmic Fistman의 대답입니다. 필요한 import 문과 위임 방법이 있습니다.

import UIKit 
import AVFoundation 

class ViewController: UIViewController, 
AVCaptureFileOutputRecordingDelegate { 

var captureSession = AVCaptureSession() 
var sessionOutput = AVCaptureStillImageOutput() 
var movieOutput = AVCaptureMovieFileOutput() 
var previewLayer = AVCaptureVideoPreviewLayer() 

@IBOutlet var cameraView: UIView! 

override func viewWillAppear(_ animated: Bool) { 
    self.cameraView = self.view 

    let devices = AVCaptureDevice.devices(withMediaType: AVMediaTypeVideo) 
    for device in devices! { 
     if (device as AnyObject).position == AVCaptureDevicePosition.front{ 


      do{ 

       let input = try AVCaptureDeviceInput(device: device as! AVCaptureDevice) 

       if captureSession.canAddInput(input){ 

        captureSession.addInput(input) 
        sessionOutput.outputSettings = [AVVideoCodecKey : AVVideoCodecJPEG] 

        if captureSession.canAddOutput(sessionOutput){ 

         captureSession.addOutput(sessionOutput) 

         previewLayer = AVCaptureVideoPreviewLayer(session: captureSession) 
         previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill 
         previewLayer.connection.videoOrientation = AVCaptureVideoOrientation.portrait 
         cameraView.layer.addSublayer(previewLayer) 

         previewLayer.position = CGPoint(x: self.cameraView.frame.width/2, y: self.cameraView.frame.height/2) 
         previewLayer.bounds = cameraView.frame 


        } 

        captureSession.addOutput(movieOutput) 

        captureSession.startRunning() 

        let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask) 
        let fileUrl = paths[0].appendingPathComponent("output.mov") 
        try? FileManager.default.removeItem(at: fileUrl) 
        movieOutput.startRecording(toOutputFileURL: fileUrl, recordingDelegate: self) 

        let delayTime = DispatchTime.now() + 5 
        DispatchQueue.main.asyncAfter(deadline: delayTime) { 
         print("stopping") 
         self.movieOutput.stopRecording() 
        } 
       } 

      } 
      catch{ 

       print("Error") 
      } 

     } 
    } 

} 


//MARK: AVCaptureFileOutputRecordingDelegate Methods 

func capture(_ captureOutput: AVCaptureFileOutput!, didStartRecordingToOutputFileAt fileURL: URL!, fromConnections connections: [Any]!) { 

} 

func capture(_ captureOutput: AVCaptureFileOutput!, didFinishRecordingToOutputFileAt outputFileURL: URL!, fromConnections connections: [Any]!, error: Error!) { 
    print("FINISHED \(error)") 
    // save video to camera roll 
    if error == nil { 
     UISaveVideoAtPathToSavedPhotosAlbum(outputFileURL.path, nil, nil, nil) 
    } 
} 

}

+0

비디오는 라이브러리에 잘 기록되고 저장되지만 사운드는 녹음되지 않습니다. 도와주세요. – iDev750

0

if (device as AnyObject).position == AVCaptureDevicePosition.front{

// Audio Input 
       let audioInputDevice = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeAudio) 

       do 
       { 
        let audioInput = try AVCaptureDeviceInput(device: audioInputDevice) 

        // Add Audio Input 
        if captureSession.canAddInput(audioInput) 
        { 
         captureSession.addInput(audioInput) 
        } 
        else 
        { 
         NSLog("Can't Add Audio Input") 
        } 
       } 
       catch let error 
       { 
        NSLog("Error Getting Input Device: \(error)") 
       } 

감사

소리 녹음 문제에 대한
0

을 추가

captureSession

askMicroPhonePermission (완료 만들 때

이 코드를 추가

  if isMicrophonePermissionGiven { 
       do { 
        try self.captureSession.addInput(AVCaptureDeviceInput(device: self.captureAudio)) 
       } catch { 
        print("Error creating the database") 
       } 
      } 
     }) 

에서 {(isMicrophonePermissionGiven를) ///////////////////// /////////////////////////////////

askMicroPhonePermission function is

func askMicroPhonePermission(completion: @escaping (_ success: Bool)-> Void) { 
    switch AVAudioSession.sharedInstance().recordPermission() { 
    case AVAudioSessionRecordPermission.granted: 
     completion(true) 
    case AVAudioSessionRecordPermission.denied: 
     completion(false) //show alert if required 
    case AVAudioSessionRecordPermission.undetermined: 
     AVAudioSession.sharedInstance().requestRecordPermission({ (granted) in 
      if granted { 
       completion(true) 
      } else { 
       completion(false) // show alert if required 
      } 
     }) 
    default: 
     completion(false) 
    } 
} 

그리고 NSMicrophoneUsageDescription 키를 추가해야합니다. info.plist 파일의 값.

관련 문제