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

前端之家收集整理的这篇文章主要介绍了通过AVFoundation获取摄像头数据[Swift]前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

真的好久没写Blog了。。囧

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

AVCaptureSession
AVCaptureDeviceInput
AVCaptureVideoDataOutput
AVCaptureVideoPreviewLayer


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 UIKit
import AVFoundation

class 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),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,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

原文链接:https://www.f2er.com/swift/325334.html

猜你在找的Swift相关文章