Подтвердить что ты не робот

Захват видео с помощью Swift с использованием AVCaptureVideoDataOutput или AVCaptureMovieFileOutput

Мне нужно некоторое руководство по захвату видео без использования UIImagePicker. Видео нужно запустить и остановить нажатием кнопки, а затем эти данные будут сохранены в NSDocumentDirectory. Я новичок в быстрой, поэтому любая помощь будет полезна.

Раздел кода, в котором мне нужна помощь, запускает и останавливает сеанс видео и превращает это в данные. Я создал версию с картинкой, которая запускает captureStillImageAsynchronouslyFromConnection и сохраняет эти данные в NSDocumentDirectory. Я установил сеанс видеозахвата и готов код для сохранения данных, но не знаю, как получить данные из сеанса.

var previewLayer : AVCaptureVideoPreviewLayer?
var captureDevice : AVCaptureDevice?
var videoCaptureOutput = AVCaptureVideoDataOutput()

let captureSession = AVCaptureSession()

override func viewDidLoad() {
    super.viewDidLoad()

    captureSession.sessionPreset = AVCaptureSessionPreset640x480
    let devices = AVCaptureDevice.devices()

    for device in devices {
        if (device.hasMediaType(AVMediaTypeVideo)) {
            if device.position == AVCaptureDevicePosition.Back {
                captureDevice = device as? AVCaptureDevice
                if captureDevice != nil {
                    beginSession()
                }
            }   
        }
    }
}

func beginSession() {
    var err : NSError? = nil
    captureSession.addInput(AVCaptureDeviceInput(device: captureDevice, error: &err))

    if err != nil {
        println("Error: \(err?.localizedDescription)")
    }

    videoCaptureOutput.videoSettings = [kCVPixelBufferPixelFormatTypeKey:kCVPixelFormatType_32BGRA]
    videoCaptureOutput.alwaysDiscardsLateVideoFrames = true

    captureSession.addOutput(videoCaptureOutput)

    previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
    self.view.layer.addSublayer(previewLayer)
    previewLayer?.frame = CGRectMake(0, 0, screenWidth, screenHeight)
    captureSession.startRunning()

    var startVideoBtn = UIButton(frame: CGRectMake(0, screenHeight/2, screenWidth, screenHeight/2))
        startVideoBtn.addTarget(self, action: "startVideo", forControlEvents: UIControlEvents.TouchUpInside)
        self.view.addSubview(startVideoBtn)

    var stopVideoBtn = UIButton(frame: CGRectMake(0, 0, screenWidth, screenHeight/2))
        stopVideoBtn.addTarget(self, action: "stopVideo", forControlEvents: UIControlEvents.TouchUpInside)
        self.view.addSubview(stopVideoBtn)
}

Я могу предоставить больше кода или объяснений, если это необходимо.

4b9b3361

Ответ 1

Для получения наилучших результатов прочитайте раздел Still and Video Media Capture из Руководство по программированию AV Foundation.

Для обработки кадров из AVCaptureVideoDataOutput вам понадобится делегат, который принимает протокол AVCaptureVideoDataOutputSampleBufferDelegate. Метод делегата captureOutput будет вызываться всякий раз, когда записывается новый кадр. Когда вы устанавливаете делегат выходов, вы также должны предоставлять очередь, по которой должны быть вызваны обратные вызовы. Он будет выглядеть примерно так:

let cameraQueue = dispatch_queue_create("cameraQueue", DISPATCH_QUEUE_SERIAL)
videoCaptureOutput.setSampleBufferDelegate(myDelegate, queue: cameraQueue)
captureSession.addOutput(videoCaptureOutput)

Примечание: Если вы хотите сохранить фильм в файл, вы можете предпочесть класс AVCaptureMovieFileOutput вместо AVCaptureVideoDataOutput. В этом случае вам не понадобится очередь. Но вам все равно понадобится делегат, на этот раз вместо которого будет принят протокол AVCaptureFileOutputRecordingDelegate. (Соответствующий метод все еще называется captureOutput.)

Здесь один отрывок из части о AVCaptureMovieFileOutput из руководства, связанного с выше:

Запуск записи

Вы начинаете запись фильма QuickTime с помощью startRecordingToOutputFileURL:recordingDelegate:. Вам необходимо предоставить URL-адрес на основе файлов и делегат. URL не должен идентифицировать существующие файл, потому что выход файла видео не перезаписывает существующие Ресурсы. Вы также должны иметь разрешение на запись в указанный место нахождения. Делегат должен соответствовать AVCaptureFileOutputRecordingDelegate и должен реализовать captureOutput:didFinishRecordingToOutputFileAtURL:fromConnections:error:Метод.

AVCaptureMovieFileOutput *aMovieFileOutput = <#Get a movie file output#>;
NSURL *fileURL = <#A file URL that identifies the output location#>;
[aMovieFileOutput startRecordingToOutputFileURL:fileURL recordingDelegate:<#The delegate#>];

В реализации captureOutput:didFinishRecordingToOutputFileAtURL:fromConnections:error:, делегат может записать полученный фильм в альбом Camera Roll. Он также должен проверить наличие ошибок, которые могли произойти.