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()
}
}
你確定'captureVideo()'被實際調用嗎?如果是這樣,請在使用'captureSession.running'錄製之前檢查會話是否真的在運行。也許問題不是直接與捕獲有關,而是與按鈕事件或捕獲會話配置有關。 – fluidsonic
感謝您的回覆@fluidsonic。當我點擊按鈕時,在調用captureVideo()之前,我現在已經檢查並且'captureSession.running'等於'true'。有什麼建議麼? – sondrelevi