2016-09-10 19 views
9

Xin chào Tôi đã theo một khóa học của Jared Davidson để tạo chế độ xem máy ảnh tùy chỉnh và lưu ảnh bằng AVFoundation. https://www.youtube.com/watch?v=w0O3ZGUS3pkLưu Video Sử dụng AVFoundation Swift

Tuy nhiên, tôi muốn ghi lại và lưu video thay vì hình ảnh. Ai đó có thể giúp tôi ở đây không? Tôi chắc chắn tài liệu đơn giản nhưng táo của nó được viết trong Objective-C và tôi không thể giải mã nó.

Đây là mã của tôi. Cảm ơn.

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) 

      }) 

     } 

    } 

} 

Trả lời

15

Bạn có thể lưu ghi lại video của bạn để nộp bằng cách tạo ra và thêm một AVCaptureMovieFileOutput phiên chụp của bạn, và làm cho ViewController của bạn phù hợp với các AVCaptureFileOutputRecordingDelegate.

Ví dụ này ghi 5 giây video vào tệp có tên "output.mov" trong thư mục Documents của ứng dụng.

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

Bạn có thể tải xuống thư mục Documents từ thiết bị trong Xcode> Thiết bị> iPhone> _app name_> Tải xuống vùng chứa. Bạn có thể lưu video vào thư viện ảnh bằng cách gọi 'UISaveVideoAtPathToSavedPhotosAlbum()' từ phương thức ủy nhiệm 'didFinishRecordingToOutputFileAtURL'. Nếu câu hỏi của bạn được trả lời, vui lòng chấp nhận câu trả lời này. –

+1

Haha cảm ơn rất nhiều! Hy vọng rằng điều này sẽ giúp người khác cũng bởi vì tôi thấy rất nhiều người đã hỏi. –

5

Cảm ơn bạn vì điều này. Nó rất hữu ích cho tôi. Đây là một phiên bản của câu trả lời của Rhythmic Fistman được chuyển đến Swift 3 với các câu lệnh nhập và phương thức ủy nhiệm được yêu cầu.

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

Video đang ghi và lưu trong thư viện tốt nhưng âm thanh không được ghi lại. Làm ơn giúp tôi. – iDev750

0

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

thêm

// 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)") 
       } 

Cảm ơn

0

Đối với các vấn đề ghi âm,

Thêm mã này khi tạo captureSession

askMicroPhonePermission (hoàn thành: {(isMicrophonePermissionGiven) trong

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

///////////////////// ///////////////////////////////////////////////////////////

chức năng askMicroPhonePermission là như sau

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) 
    } 
} 

Và bạn phải thêm khóa NSMicrophoneUsageDescription giá trị trong tệp info.plist.

Các vấn đề liên quan