AVCaptureDevice
枚舉說明部分
AVCaptureDeviceType | 枚舉說明 |
---|---|
AVCaptureDeviceTypeBuiltInMicrophone | 一個內(nèi)置的麥克風(fēng) |
AVCaptureDeviceTypeBuiltInWideAngleCamera | 內(nèi)置廣角相機,這些裝置適用于一般用途 |
AVCaptureDeviceTypeBuiltInTelephotoCamera | 內(nèi)置長焦相機冤留,比廣角相機的焦距長。這種類型只是將窄角設(shè)備與配備兩種類型的攝像機的硬件上的寬角設(shè)備區(qū)分開來 |
AVCaptureDeviceTypeBuiltInDualCamera | 廣角相機和長焦相機的組合遮婶,創(chuàng)建了一個拍照 (常用類型) |
AVCaptureDeviceTypeBuiltInTelephotoCamera | 創(chuàng)建比廣角相機更長的焦距剥险。只有使用 AVCaptureDeviceDiscoverySession 可以使用 |
AVCaptureDeviceTypeBuiltInDuoCamera | iOS 10.2 被 AVCaptureDeviceTypeBuiltInDualCamera 替換 |
接下來是AVMediaType的枚舉說明.未補充完整后續(xù)查閱資料來補齊.
AVMediaType | 枚舉說明 |
---|---|
AVMediaTypeVideo | 視頻 |
AVMediaTypeAudio | 音頻 |
AVMediaTypeText | 文本 |
AVMediaTypeClosedCaption | 電影 |
AVMediaTypeSubtitle | AVMediaTypeSubtitle |
AVMediaTypeTimecode | AVMediaTypeTimecode |
AVMediaTypeMetadata | AVMediaTypeMetadata |
AVMediaTypeMuxed | 音頻 + 視頻 |
還有一個攝像頭的枚舉部分.
AVCaptureDevicePosition | 枚舉說明 |
---|---|
AVCaptureDevicePositionUnspecified | 未指定的設(shè)備 |
AVCaptureDevicePositionBack | 后攝像頭 手機屏幕背面的攝像頭 |
AVCaptureDevicePositionFront | 前攝像頭 手機屏幕上邊的攝像頭 |
攝像頭的權(quán)限的枚舉說明
AVAuthorizationStatus | 攝像頭權(quán)限說明 |
---|---|
AVAuthorizationStatusNotDetermined | 用戶暫時沒有授權(quán) |
AVAuthorizationStatusRestricted | 沒有改變媒體類型 |
AVAuthorizationStatusDenied | 用戶允許 |
AVAuthorizationStatusAuthorized | 用戶 拒絕 |
思路 : 拿到攝像頭->開啟攝像頭->捕捉畫面->拿到數(shù)據(jù) 下面開始寫代碼
//
// XJCaptureSesion.m
// AVFoundation
//
// Created by 張孝江 on 2021/4/1.
//
#import "XJCaptureManager.h"
#import <AVFoundation/AVFoundation.h>
@interface XJCaptureManager()<AVCaptureVideoDataOutputSampleBufferDelegate>
/**最主要的一個類**/
@property (nonatomic,strong) AVCaptureSession *session;
@property (nonatomic,strong) dispatch_queue_t sessionQueue; //線程的隊列
/*設(shè)備的抽象的類 輸入*/
@property (nonatomic, strong) AVCaptureDeviceInput *frontCamera;
@property (nonatomic, strong) AVCaptureDeviceInput *backCamera;
@property (nonatomic, weak) AVCaptureDeviceInput *currentCamera;
/**抽象類, 輸出**/
@property (nonatomic,strong) AVCaptureVideoDataOutput *videoDataOutput; // 這個是視頻的輸出的類.
@property (nonatomic, strong) AVCaptureConnection *videoConnection;
/**抽象類預(yù)覽測**/
@property (nonatomic,strong) AVCaptureVideoPreviewLayer *preLayer; //預(yù)覽層
@end
@implementation XJCaptureManager
-(instancetype)init{
if (self = [super init]) {
[self initVideo];
}
return self;
}
-(void)startLive{
[self.session startRunning];
}
#pragma mark - 開始捕捉..
-(void)initVideo{
/**第一步獲取攝像頭**/
AVCaptureDevice * front = [AVCaptureDevice defaultDeviceWithDeviceType:AVCaptureDeviceTypeBuiltInWideAngleCamera mediaType:AVMediaTypeVideo position:AVCaptureDevicePositionFront];
self.frontCamera = [AVCaptureDeviceInput deviceInputWithDevice: front error:NULL];
AVCaptureDevice *back = [AVCaptureDevice defaultDeviceWithDeviceType:AVCaptureDeviceTypeBuiltInWideAngleCamera mediaType:AVMediaTypeVideo position:AVCaptureDevicePositionBack];
self.backCamera = [AVCaptureDeviceInput deviceInputWithDevice:back error:NULL];
//設(shè)置默認選項為前置攝像頭
self.currentCamera = self.frontCamera;
//設(shè)置視頻的輸出..
[self.videoDataOutput setSampleBufferDelegate:self queue:self.sessionQueue];
//會丟失處理不過來的幀數(shù)據(jù).
[self.videoDataOutput setAlwaysDiscardsLateVideoFrames:YES];
//設(shè)置輸出格式..
NSDictionary *dictionary = @{
(__bridge NSString *)kCVPixelBufferPixelFormatTypeKey:@(kCVPixelFormatType_420YpCbCr8BiPlanarFullRange)
};
//當(dāng)你不知所錯的時候 記得點開看一下
/*
On iOS, the only supported key is kCVPixelBufferPixelFormatTypeKey. Supported pixel formats are kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange, kCVPixelFormatType_420YpCbCr8BiPlanarFullRange and kCVPixelFormatType_32BGRA.
*/
[self.videoDataOutput setVideoSettings:dictionary];
//配置輸入
[self.session beginConfiguration];
if ([self.session canAddInput:self.currentCamera]) {
[self.session addInput:self.currentCamera];
}
//配置輸出
if ([self.session canAddOutput:self.videoDataOutput]) {
[self.session addOutput:self.videoDataOutput];
}
//設(shè)置分辨率
if ([self.session canSetSessionPreset:AVCaptureSessionPreset1920x1080]) {
self.session.sessionPreset = AVCaptureSessionPreset1920x1080;
}else if ([self.session canSetSessionPreset:AVCaptureSessionPreset1280x720]){
self.session.sessionPreset = AVCaptureSessionPreset1280x720;
}else if ([self.session canSetSessionPreset:AVCaptureSessionPreset640x480]){
self.session.sessionPreset = AVCaptureSessionPreset640x480;
}else{
self.session.sessionPreset = AVCaptureSessionPreset352x288;
}
//結(jié)尾
[self.session commitConfiguration];
self.videoConnection = [self.videoDataOutput connectionWithMediaType:AVMediaTypeVideo];
//設(shè)置視頻的輸出方向
self.videoConnection.videoOrientation = AVCaptureVideoOrientationPortrait;
//設(shè)置分辨率..
[self setUpdataFps:30];
//設(shè)置預(yù)覽層...
[self.preview.layer addSublayer:self.preLayer];
}
#pragma mark - 根據(jù)代理取獲取的文件的地址. 這就是當(dāng)前獲取的樣本...
-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection{
NSLog(@"%@",sampleBuffer);
}
#pragma mark - 設(shè)置分辨率......
-(void)setUpdataFps:(NSInteger)fps{
AVCaptureDevice *front = [AVCaptureDevice defaultDeviceWithDeviceType:AVCaptureDeviceTypeBuiltInWideAngleCamera mediaType:AVMediaTypeVideo position:AVCaptureDevicePositionFront];
AVCaptureDevice *back = [AVCaptureDevice defaultDeviceWithDeviceType:AVCaptureDeviceTypeBuiltInWideAngleCamera mediaType:AVMediaTypeVideo position:AVCaptureDevicePositionBack];
NSArray *array = @[front,back];
for (AVCaptureDevice *device in array) {
//獲取當(dāng)前支持的最大的FPS
Float64 a = device.activeFormat.videoSupportedFrameRateRanges.firstObject.maxFrameRate;
if (a >= fps) {
if ([device lockForConfiguration:NULL]) {
device.activeVideoMinFrameDuration = CMTimeMake(10, (int)(fps * 10));
device.activeVideoMaxFrameDuration = device.activeVideoMinFrameDuration;
[device unlockForConfiguration];
}
}
}
}
-(void)dealloc{
NSLog(@"我銷毀了");
}
/*簡單的初始化*/
-(AVCaptureSession *)session{
if (!_session) {
_session = [[AVCaptureSession alloc]init];
}
return _session;
}
/*初始化輸出的類*/
-(AVCaptureVideoDataOutput *)videoDataOutput{
if (!_videoDataOutput) {
_videoDataOutput = [[AVCaptureVideoDataOutput alloc]init];
}
return _videoDataOutput;
}
-(dispatch_queue_t)sessionQueue{
if (!_sessionQueue) {
_sessionQueue = dispatch_queue_create("XJ.SESSION", NULL);
}
return _sessionQueue;
}
-(AVCaptureVideoPreviewLayer *)preLayer{
if (!_preLayer) {
_preLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.session];
_preLayer.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);
_preLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
}
return _preLayer;
}
-(UIView *)preview{
if (!_preview) {
_preview = [[UIView alloc] init];
}
return _preview;
}
@end
在代理回調(diào)的地方就可以拿到這個視頻的數(shù)據(jù)..