首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用AVCaptureVideoDataOutput或AVCaptureMovieFileOutput快速捕获视频

用AVCaptureVideoDataOutput或AVCaptureMovieFileOutput快速捕获视频
EN

Stack Overflow用户
提问于 2014-12-22 15:47:10
回答 1查看 15K关注 0票数 16

我需要一些指导,如何在不需要使用UIImagePicker的情况下捕获视频。视频需要按一下按钮开始和停止,然后将数据保存到NSDocumentDirectory中。我是新来的斯威夫特,所以任何帮助都会有用。

我需要帮助的代码部分是启动和停止视频会话并将其转换为数据。我创建了一个运行captureStillImageAsynchronouslyFromConnection并将这些数据保存到NSDocumentDirectory的拍照版本。我已经设置了一个视频捕捉会话,并准备好了保存数据的代码,但不知道如何从会话中获取数据。

代码语言:javascript
复制
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)
}

如果需要,我可以提供更多的代码或解释。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-05-10 15:57:54

要获得最佳结果,请阅读来自https://developer.apple.com/library/mac/documentation/AudioVideo/Conceptual/AVFoundationPG/Articles/00_Introduction.html. https://developer.apple.com/library/mac/documentation/AudioVideo/Conceptual/AVFoundationPG/Articles/04_MediaCapture.html 部分。

要处理来自AVCaptureVideoDataOutput的帧,您需要一个采用AVCaptureVideoDataOutputSampleBufferDelegate协议的委托。每当编写新框架时,都会调用委托的captureOutput方法。设置输出的委托时,还必须提供一个调用回调的队列。看起来会是这样的:

代码语言:javascript
复制
let cameraQueue = dispatch_queue_create("cameraQueue", DISPATCH_QUEUE_SERIAL)
videoCaptureOutput.setSampleBufferDelegate(myDelegate, queue: cameraQueue)
captureSession.addOutput(videoCaptureOutput)

NB:如果您只想将电影保存到一个文件中,您可能更喜欢AVCaptureMovieFileOutput类而不是AVCaptureVideoDataOutput。那样的话,你就不需要排队了。但是您仍然需要一个委托,这次采用的是AVCaptureFileOutputRecordingDelegate协议。(相关方法仍然称为captureOutput。)

下面是链接到上面的指南中有关AVCaptureMovieFileOutput的部分的摘录:

开始录音 开始使用QuickTime录制startRecordingToOutputFileURL:recordingDelegate:电影。您需要提供一个基于文件的URL和一个委托。URL不能标识现有文件,因为电影文件输出不会覆盖现有资源。您还必须具有写入指定位置的权限。委托必须符合AVCaptureFileOutputRecordingDelegate协议,并且必须实现captureOutput:didFinishRecordingToOutputFileAtURL:fromConnections:error:方法。 AVCaptureMovieFileOutput *aMovieFileOutput = <#Get一个电影文件output#>;NSURL *fileURL =标识输出location#>的<#A文件URL;aMovieFileOutput startRecordingToOutputFileURL:fileURL recordingDelegate:<#The delegate#>; captureOutput:didFinishRecordingToOutputFileAtURL:fromConnections:error:的实现中,委托可以将结果电影写入相机卷相册。它还应该检查可能发生的任何错误。

票数 17
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27605913

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档