有关AVFoundation的一些类
- 捕捉会话:AVCaptureSession.
2. 捕捉设备:AVCaptureDevice.
3. 捕捉设备输入:AVCaptureDeviceInput
4. 捕捉设备输出: AVCaptureOutput .
a. AVCaptureStillImageOutput
b. AVCaputureMovieFileOutput
c. AVCaputureAudioDataOutput
d. AVCaputureVideoDataOutput - 捕捉连接
AVCaptureConnection - 捕捉预览
AVCaptureVideoPreviewLayer
案例1. 拍照
设置会话
- (BOOL)setupSession:(NSError **)error {
//创建捕捉会话。AVCaptureSession 是捕捉场景的中心枢纽
self.captureSession = [[AVCaptureSession alloc]init];
/*
AVCaptureSessionPresetHigh
AVCaptureSessionPresetMedium
AVCaptureSessionPresetLow
AVCaptureSessionPreset640x480
AVCaptureSessionPreset1280x720
AVCaptureSessionPresetPhoto
*/
//设置图像的分辨率
self.captureSession.sessionPreset = AVCaptureSessionPresetHigh;
//拿到默认视频捕捉设备 iOS系统返回后置摄像头
AVCaptureDevice *videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
//将捕捉设备封装成AVCaptureDeviceInput
//注意:为会话添加捕捉设备,必须将设备封装成AVCaptureDeviceInput对象
AVCaptureDeviceInput *videoInput = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:error];
//判断videoInput是否有效
if (videoInput)
{
//canAddInput:测试是否能被添加到会话中
if ([self.captureSession canAddInput:videoInput])
{
//将videoInput 添加到 captureSession中
[self.captureSession addInput:videoInput];
self.activeVideoInput = videoInput;
}
}else
{
return NO;
}
//AVCaptureStillImageOutput 实例 从摄像头捕捉图片
self.imageOutput = [[AVCapturePhotoOutput alloc]init];
//输出连接 判断是否可用,可用则添加到输出连接中去
if ([self.captureSession canAddOutput:self.imageOutput])
{
[self.captureSession addOutput:self.imageOutput];
}
self.videoQueue = dispatch_queue_create("test.VideoQueue", NULL);
return YES;
}
开始与结束会话
- (void)startSession {
//检查是否处于运行状态
if (![self.captureSession isRunning])
{
//使用同步调用会损耗一定的时间,则用异步的方式处理
dispatch_async(self.videoQueue, ^{
[self.captureSession startRunning];
});
}
}
- (void)stopSession {
//检查是否处于运行状态
if ([self.captureSession isRunning])
{
//使用异步方式,停止运行
dispatch_async(self.videoQueue, ^{
[self.captureSession stopRunning];
});
}
}
预览(也就是显示)
- (void)loadView{
self.view = self.previewView;
}
#import "VFPreviewView.h"
#import <AVFoundation/AVFoundation.h>
@implementation VFPreviewView
+ (Class)layerClass{
return [AVCaptureVideoPreviewLayer class];
}
@end
获取设备方向
//获取方向值
- (AVCaptureVideoOrientation)currentVideoOrientation {
AVCaptureVideoOrientation orientation;
//获取UIDevice 的 orientation
switch ([UIDevice currentDevice].orientation) {
case UIDeviceOrientationPortrait:
orientation = AVCaptureVideoOrientationPortrait;
break;
case UIDeviceOrientationLandscapeRight:
orientation = AVCaptureVideoOrientationLandscapeLeft;
break;
case UIDeviceOrientationPortraitUpsideDown:
orientation = AVCaptureVideoOrientationPortraitUpsideDown;
break;
default:
orientation = AVCaptureVideoOrientationLandscapeRight;
break;
}
return orientation;
return 0;
}
采集信息
- (void)captureOutput:(AVCapturePhotoOutput *)captureOutput didFinishProcessingPhotoSampleBuffer:(nullable CMSampleBufferRef)photoSampleBuffer previewPhotoSampleBuffer:(nullable CMSampleBufferRef)previewPhotoSampleBuffer resolvedSettings:(AVCaptureResolvedPhotoSettings *)resolvedSettings bracketSettings:(nullable AVCaptureBracketedStillImageSettings *)bracketSettings error:(nullable NSError *)error {
NSData *data = [AVCapturePhotoOutput JPEGPhotoDataRepresentationForJPEGSampleBuffer:photoSampleBuffer previewPhotoSampleBuffer:previewPhotoSampleBuffer];
UIImage *image = [UIImage imageWithData:data];
[self writeImageToAssetsLibrary:image];
}
案例2: 录制视频
预览跟拍照完全一致
1.设置会话
- (BOOL)setupSession:(NSError **)error {
//创建捕捉会话。AVCaptureSession 是捕捉场景的中心枢纽
self.captureSession = [[AVCaptureSession alloc]init];
/*
AVCaptureSessionPresetHigh
AVCaptureSessionPresetMedium
AVCaptureSessionPresetLow
AVCaptureSessionPreset640x480
AVCaptureSessionPreset1280x720
AVCaptureSessionPresetPhoto
*/
//设置图像的分辨率
self.captureSession.sessionPreset = AVCaptureSessionPresetHigh;
//拿到默认视频捕捉设备 iOS系统返回后置摄像头
AVCaptureDevice *videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
//将捕捉设备封装成AVCaptureDeviceInput
//注意:为会话添加捕捉设备,必须将设备封装成AVCaptureDeviceInput对象
AVCaptureDeviceInput *videoInput = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:error];
//判断videoInput是否有效
if (videoInput)
{
//canAddInput:测试是否能被添加到会话中
if ([self.captureSession canAddInput:videoInput])
{
//将videoInput 添加到 captureSession中
[self.captureSession addInput:videoInput];
self.activeVideoInput = videoInput;
}
}else
{
return NO;
}
//选择默认音频捕捉设备 即返回一个内置麦克风
AVCaptureDevice *audioDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];
//为这个设备创建一个捕捉设备输入
AVCaptureDeviceInput *audioInput = [AVCaptureDeviceInput deviceInputWithDevice:audioDevice error:error];
//判断audioInput是否有效
if (audioInput) {
//canAddInput:测试是否能被添加到会话中
if ([self.captureSession canAddInput:audioInput])
{
//将audioInput 添加到 captureSession中
[self.captureSession addInput:audioInput];
}
}else
{
return NO;
}
//创建一个AVCaptureMovieFileOutput 实例,用于将Quick Time 电影录制到文件系统
self.movieOutput = [[AVCaptureMovieFileOutput alloc]init];
//输出连接 判断是否可用,可用则添加到输出连接中去
if ([self.captureSession canAddOutput:self.movieOutput])
{
[self.captureSession addOutput:self.movieOutput];
}
self.videoQueue = dispatch_queue_create("test.VideoQueue", NULL);
return YES;
}
2.判断是否录制状态
- (BOOL)isRecording {
return self.movieOutput.isRecording;
}
3.开始录制
- (void)startRecording {
if (![self isRecording]) {
//获取当前视频捕捉连接信息,用于捕捉视频数据配置一些核心属性
AVCaptureConnection * videoConnection = [self.movieOutput connectionWithMediaType:AVMediaTypeVideo];
//判断是否支持设置videoOrientation 属性。
if([videoConnection isVideoOrientationSupported])
{
//支持则修改当前视频的方向
videoConnection.videoOrientation = [self currentVideoOrientation];
}
//判断是否支持视频稳定 可以显著提高视频的质量。只会在录制视频文件涉及
if([videoConnection isVideoStabilizationSupported])
{
videoConnection.enablesVideoStabilizationWhenAvailable = YES;
}
AVCaptureDevice *device = self.activeVideoInput.device;
//摄像头可以进行平滑对焦模式操作。即减慢摄像头镜头对焦速度。当用户移动拍摄时摄像头会尝试快速自动对焦。
if (device.isSmoothAutoFocusEnabled) {
NSError *error;
if ([device lockForConfiguration:&error]) {
device.smoothAutoFocusEnabled = YES;
[device unlockForConfiguration];
}else
{
NSLog(@"失败");
}
}
//查找写入捕捉视频的唯一文件系统URL.
self.outputURL = [self uniqueURL];
//在捕捉输出上调用方法 参数1:录制保存路径 参数2:代理
[self.movieOutput startRecordingToOutputFileURL:self.outputURL recordingDelegate:self];
}
}
录制视频采集
#pragma mark - AVCaptureFileOutputRecordingDelegate
- (void)captureOutput:(AVCaptureFileOutput *)captureOutput
didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL
fromConnections:(NSArray *)connections
error:(NSError *)error {
//错误
if (error) {
NSLog(@"失败");
}else
{
//写入
[self writeVideoToAssetsLibrary:[self.outputURL copy]];
}
self.outputURL = nil;
}
最后送上github地址