2015-12-01 25 views
0

我的視圖控制器包含一個預覽圖層,它可以從我的相機實時投影圖像。按住按鈕時,我的代碼應該記錄一個視頻,並將其寫入本地臨時文件。這適用於Swift 1.2和Xcode 6,但在更新到Xcode 7後將代碼轉換爲Swift 2後停止工作。AVCaptureFileOutputRecordingDelegate不寫入文件,Swift 2

當我釋放按鈕時,captureOutput不會被調用,並且存在沒有寫入給定路徑的文件。

一些相關的代碼如下。

我將不勝感激任何幫助!

import UIKit 
import MobileCoreServices 
import AVFoundation 
import AVKit 




class ViewControllerPhoto: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate, UIPickerViewDelegate, UIGestureRecognizerDelegate, ACEDrawingViewDelegate, UITextViewDelegate, AVCaptureFileOutputRecordingDelegate, UITableViewDelegate, UITableViewDataSource { 

    @IBOutlet weak var captureButton: UIButton! 

    var videoCheck: Bool = false 

    let captureSession = AVCaptureSession() 
    var previewLayer : AVCaptureVideoPreviewLayer? 
    var captureDevice : AVCaptureDevice? 

    var movieFileOutput = AVCaptureMovieFileOutput() 
    var imageData: NSData! 
    var outputPath: NSString! 
    var outputURL: NSURL! 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     // Do any additional setup after loading the view, typically from a nib. 


     if captureSession.canSetSessionPreset(AVCaptureSessionPresetMedium) { 

     captureSession.sessionPreset = AVCaptureSessionPresetMedium 

     } 

     let devices = AVCaptureDevice.devices() 

     // Loop through all the capture devices on this phone 
     for device in devices { 
      // Make sure this particular device supports video 
      if (device.hasMediaType(AVMediaTypeVideo)) { 
       // Finally check the position and confirm we've got the back camera 
       if(device.position == AVCaptureDevicePosition.Back) { 
        captureDevice = device as? AVCaptureDevice 
        if captureDevice != nil { 
         print("Capture device found") 


         beginSession() 
        } 
       } 
      } 

     } 

     self.videoCheck = false 

    } 

    func beginSession() { 

     stillImageOutput.outputSettings = [AVVideoCodecKey: AVVideoCodecJPEG] 
     if captureSession.canAddOutput(stillImageOutput) { 
      captureSession.addOutput(stillImageOutput) 
     } 
     configureDevice() 

     var err : NSError? = nil 
     // captureSession.addInput(AVCaptureDeviceInput(device: captureDevice, error: &err)) 
     do{ 
     try captureSession.addInput(AVCaptureDeviceInput(device: captureDevice)) 
     } 
     catch{ 
      print("error: \(err?.localizedDescription)") 
     } 

     previewLayer = AVCaptureVideoPreviewLayer(session: captureSession) 
     self.view.layer.addSublayer(previewLayer!) 
     previewLayer?.frame = self.view.layer.frame 

     previewLayer?.videoGravity = AVLayerVideoGravityResizeAspectFill 

     if captureSession.canAddOutput(movieFileOutput) { 

      self.captureSession.addOutput(movieFileOutput) 

     } 

     // SET CONNECTION PROPERTIES 

     var captureConnection: AVCaptureConnection = movieFileOutput.connectionWithMediaType(AVMediaTypeVideo) 
     if captureConnection.supportsVideoOrientation { 

     captureConnection.videoOrientation = AVCaptureVideoOrientation.Portrait 

     } 

     var audioDevice: AVCaptureDevice = AVCaptureDevice.devicesWithMediaType(AVMediaTypeAudio)[0] as! AVCaptureDevice 
     do{ 

     let audioDeviceInput: AVCaptureDeviceInput = try AVCaptureDeviceInput(device: audioDevice) 
      if captureSession.canAddInput(audioDeviceInput) { 

       captureSession.addInput(audioDeviceInput) 

      } 
     } 
     catch { 
      print("error") 
     } 

     captureSession.startRunning() 
    } 



    func captureVideo() { 
     outputPath = (NSURL(fileURLWithPath: NSTemporaryDirectory())).URLByAppendingPathComponent("movie.mov").absoluteString as NSString 

outputURL = NSURL(fileURLWithPath: outputPath as String) 

     let fileManager: NSFileManager = NSFileManager.defaultManager() 

     if outputURL.path != nil{ 

      if fileManager.fileExistsAtPath(outputURL.path!) { 

       do{ 
        try fileManager.removeItemAtPath(outputPath as String) 

       } 
       catch{ 
       print(error) 
       } 

      } 
     } 
     self.movieFileOutput.startRecordingToOutputFileURL(outputURL, recordingDelegate: self) 

    } 


    func cameraWithPosition(position: AVCaptureDevicePosition) -> AVCaptureDevice { 
     let devices: NSArray = AVCaptureDevice.devicesWithMediaType(AVMediaTypeVideo) 
     for device in devices { 
      if(device.position == position){ 
       return device as! AVCaptureDevice 
      } 
     } 
     return AVCaptureDevice() 
    } 

    @IBAction func captureButtonIsLongPressed(sender: UILongPressGestureRecognizer) { 

     if sender.state == UIGestureRecognizerState.Began { 

      videoCheck = true 
      captureVideo() 

     } 

     else if sender.state == UIGestureRecognizerState.Ended{ 

      self.movieFileOutput.stopRecording() 

     } 

    } 

    func captureOutput(captureOutput: AVCaptureFileOutput!, didFinishRecordingToOutputFileAtURL outputFileURL: NSURL!, fromConnections connections: [AnyObject]!, error: NSError!) { 
     print("Output") 

     playVideo() 

    } 
    func playVideo() { 

     let path = outputPath 
     let url = outputURL 

let player = AVPlayer(URL: url) 
     let playerLayer = AVPlayerLayer(player: player) 
     playerLayer.frame = self.view.bounds 

     player.play() 

    } 

} 
+0

你確定'captureVideo()'被實際調用嗎?如果是這樣,請在使用'captureSession.running'錄製之前檢查會話是否真的在運行。也許問題不是直接與捕獲有關,而是與按鈕事件或捕獲會話配置有關。 – fluidsonic

+0

感謝您的回覆@fluidsonic。當我點擊按鈕時,在調用captureVideo()之前,我現在已經檢查並且'captureSession.running'等於'true'。有什麼建議麼? – sondrelevi

回答

1

經過大量的謎語後發現它。我的錯誤是在線

outputPath = (NSURL(fileURLWithPath: NSTemporaryDirectory())).URLByAppendingPathComponent("movie.mov").absoluteString as NSString 

當然,這是一個NSString,而不是NSPath。更改爲這些行解決了我的問題:

outputURL = NSURL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true).URLByAppendingPathComponent("movie.mov") 
outputPath = outputURL.path 

希望這可以幫助任何人!