通过AVFoundation获取摄像头数据[Swift]

来源:互联网 发布:php quot 转成符号 编辑:程序博客网 时间:2024/04/29 10:09

真的好久没写Blog了。。囧

捕捉硬件数据需要用到以下几个类

AVCaptureSessionAVCaptureDeviceInputAVCaptureVideoDataOutputAVCaptureVideoPreviewLayer


AVCaptureSession

控制着硬件的Input以及数据的Output(就理解为控制器吧)

AVCaptureDeviceInput

硬件的输入(从AVCaptureDevice对象中捕捉输入相关得数据)

AVCaptureVideoDataOutput

视频数据的输出(AVCaptureOutput的子类,捕捉输出相关得属性)

AVCaptureVideoPreviewLayer

预览视图



说下大概得逻辑

初始化Session(负责协调输入,输出数据交互)

通过AVCaptureDevice.defaultDeviceWithMediaType方法来获取 AVCaptureDevice(音频,视频) 具体看你传进去得参数而定

初始化输入,输出 对象

设置输出画质,将输入,输出 对象添加进session中

创建GCD并设置输出对象的相关回调


代码部分


检测摄像头权限是否可用以及跳转设置的函数


func checkVideoAuth() 

func openSettings()
这里的跳转设置函数是在IOS8以后才可使用的

摄像头输入输出设置的相关设置

func setupCamera() 



完整代码如下


////  ViewController.swift//  CameraExample////  Created by Peter_Qin on 15/11/20.//  Copyright © 2015年 Chin_Hui. All rights reserved.//import UIKitimport AVFoundationclass ViewController: UIViewController, AVCaptureVideoDataOutputSampleBufferDelegate, UIAlertViewDelegate {    /// 摄像头授权状态    var cameraAuthStatus: AVAuthorizationStatus!    /// 预览Layer    var captureVideoPreviewLayer: AVCaptureVideoPreviewLayer!        /// Session    var session: AVCaptureSession!        /// 硬件Input    var captureInput:AVCaptureDeviceInput!        /// 数据Output    var captureOutput:AVCaptureVideoDataOutput!        var customImgView: UIImageView!        /**     跳转至设置     */    func openSettings() {                let settingsURL:NSURL = NSURL(string:UIApplicationOpenSettingsURLString)!        UIApplication.sharedApplication().openURL(settingsURL)        }        /**     Check video authorization status     */    func checkVideoAuth() {        switch AVCaptureDevice.authorizationStatusForMediaType(AVMediaTypeVideo)        {        case AVAuthorizationStatus.Authorized://已经授权            self.cameraAuthStatus = AVAuthorizationStatus.Authorized            break        case AVAuthorizationStatus.NotDetermined:                        AVCaptureDevice.requestAccessForMediaType(AVMediaTypeVideo, completionHandler: { (granted: Bool) -> Void in                                if(granted){                    //受限制                    self.cameraAuthStatus = AVAuthorizationStatus.Restricted                    exit(0)                }                            })                        break        case AVAuthorizationStatus.Denied:            AVCaptureDevice.requestAccessForMediaType(AVMediaTypeVideo, completionHandler: { (granted: Bool) -> Void in                                if(!granted){                    //否认                    self.cameraAuthStatus = AVAuthorizationStatus.Denied                                        let warnMsg:UIAlertView = UIAlertView(title: "提示",                                                        message: "摄像头权限未未开启,点击确认跳转至设置",                                                       delegate: self,                                              cancelButtonTitle: "确认")                    warnMsg.show()                                    }                            })            break        default:            break        }    }        /**     摄像头设置相关 By Hui     */    func setupCamera() {                self.session = AVCaptureSession()        let device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)!        self.captureOutput = AVCaptureVideoDataOutput()        do{            try self.captureInput = AVCaptureDeviceInput(device: device)        }catch let error as NSError{            print(error)        }                        self.checkVideoAuth()        self.session.beginConfiguration()        //画面质量设置        self.session.sessionPreset = AVCaptureSessionPreset1920x1080        self.captureOutput.videoSettings = [kCVPixelBufferPixelFormatTypeKey:NSNumber(unsignedInt: kCVPixelFormatType_32BGRA),                                                      kCVPixelBufferWidthKey:NSNumber(integer: 1920),                                                     kCVPixelBufferHeightKey:NSNumber(integer: 1080)]                if(self.session.canAddInput(self.captureInput)){            self.session.addInput(self.captureInput)        }        if(self.session.canAddOutput(self.captureOutput)){            self.session.addOutput(self.captureOutput)        }                let subQueue:dispatch_queue_t = dispatch_queue_create("subQueue", nil)        captureOutput.setSampleBufferDelegate(self, queue: subQueue)                //预览Layer设置        self.captureVideoPreviewLayer = AVCaptureVideoPreviewLayer(session: self.session)        self.captureVideoPreviewLayer.frame = CGRectMake(self.view.frame.size.width/2 - (320/2), 0, 320, 240)        self.captureVideoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill        self.view.layer.addSublayer(self.captureVideoPreviewLayer)        self.session.commitConfiguration()            }        override func viewDidLoad() {        super.viewDidLoad()        // Do any additional setup after loading the view, typically from a nib.                self.setupCamera()                self.customImgView = UIImageView(frame: CGRectMake(self.captureVideoPreviewLayer.frame.origin.x, 250, 320, 240))        self.view.addSubview(self.customImgView)            }        override func viewWillAppear(animated: Bool) {        super.viewWillAppear(animated)        self.session.startRunning()    }        override func viewWillDisappear(animated: Bool) {        self.session.stopRunning()        super.viewWillDisappear(animated)    }        /**     数据流BufferRef转Image          - parameter sampleBuffer: 数据流          - returns: UIImage     */    func getImageData(sampleBuffer:CMSampleBuffer!)-> UIImage {            let imageBuffer:CVImageBufferRef = CMSampleBufferGetImageBuffer(sampleBuffer)!        CVPixelBufferLockBaseAddress(imageBuffer, 0)                let bytesPerRow:size_t = CVPixelBufferGetBytesPerRow(imageBuffer)        let width:size_t  = CVPixelBufferGetWidth(imageBuffer)        let height:size_t = CVPixelBufferGetHeight(imageBuffer)                        let safepoint:UnsafeMutablePointer<Void> = CVPixelBufferGetBaseAddress(imageBuffer)                let bitMapInfo:UInt32 = CGBitmapInfo.ByteOrder32Little.rawValue | CGImageAlphaInfo.PremultipliedFirst.rawValue                //RGB        let colorSpace: CGColorSpaceRef = CGColorSpaceCreateDeviceRGB()!        let context:CGContextRef = CGBitmapContextCreate(safepoint, width, height, 8, bytesPerRow, colorSpace, bitMapInfo)!                let quartImage: CGImageRef = CGBitmapContextCreateImage(context)!        CVPixelBufferUnlockBaseAddress(imageBuffer, 0)                return UIImage(CGImage: quartImage, scale: 1, orientation: UIImageOrientation.Right)    }        //AVCaptureVideoDataOutputSampleBufferDelegate    func captureOutput(captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, fromConnection connection: AVCaptureConnection!){                let localImg = self.getImageData(sampleBuffer)                //GCD 主线程队列中刷新UI        dispatch_async(dispatch_get_main_queue()) { () -> Void in            self.customImgView.image = localImg        }                    }        //UIAlertViewDelegate    func alertView(alertView: UIAlertView, clickedButtonAtIndex buttonIndex: Int){                if(buttonIndex == 0){            self.openSettings()        }            }    override func didReceiveMemoryWarning() {        super.didReceiveMemoryWarning()        // Dispose of any resources that can be recreated.    }}



Developer官网有个Example 叫  AVCam-iOS

0 0