AVFoundation-实现一个系统相机

详细代码请看Demo,因代码量比较大,在这里只截取了关键API

我们需要实现的功能:

1.获取相机和音频设备
2.显示相机预览视图
3.切换摄像头
4.闪光灯
5.聚焦
6.曝光
7.手电筒
8.缩放
9.拍摄
10.录制
复制代码

用到的核心类

AVCaptureDevice 音频或视频捕获设备

AVCaptureDeviceInput 提供从捕获设备到捕获会话的媒体

AVCaptureSession 捕获会话,管理捕获活动并连接输入到输出数据流

AVCaptureStillImageOutput输出静态照片

AVCaptureMovieFileOutput 输出QuickTime视频

第一步:初始化

1.创建AVCaptureSession并设置质量

self.captureSession = [[AVCaptureSession alloc] init];

self.captureSession.sessionPreset = AVCaptureSessionPresetHigh;

2.创建视频输入设备及捕获媒体

AVCaptureDevice *videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];

AVCaptureDeviceInput *videoInput = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:error];

3.添加视频输入捕获媒体

[self.captureSession addInput:videoInput];

4.创建音频输入设备及捕获媒体

AVCaptureDevice *audioDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];

AVCaptureDeviceInput *audioInput = [AVCaptureDeviceInput deviceInputWithDevice:audioDevice error:error];

5.添加音频输入捕获媒体

[self.captureSession addInput:audioInput];

6.创建静态照片输出并加入到当前会话

self.imageOutput = [[AVCaptureStillImageOutput alloc] init];

self.imageOutput.outputSettings = @{AVVideoCodecKey : AVVideoCodecTypeJPEG};

[self.captureSession addOutput:self.imageOutput];

7.创建视频输出并加入到当前会话

self.movieOutput = [[AVCaptureMovieFileOutput alloc] init];

[self.captureSession addOutput:self.movieOutput];

第二步:启动会话

[self.captureSession startRunning];

第三步:创建预览图层,并设置AVCaptureSession会话

AVCaptureVideoPreviewLayer *layer = [AVCaptureVideoPreviewLayer layer];

[layer setSession:session];

第四步:切换摄像头

获取与当前活动摄像头相反的设备,获取对应的捕获媒体,移除之前的捕获媒体,添加新的捕获媒体

- (BOOL)switchCameras
{
    if (![self canSwitchCameras]) return NO;
    NSError *error;
    AVCaptureDevice *videoDevice = [self inactiveCamera];
    AVCaptureDeviceInput *videoInput = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:&error];
    if (videoInput) {
        [self.captureSession beginConfiguration];
        [self.captureSession removeInput:self.activeVideoInput];
        if ([self.captureSession canAddInput:videoInput]) {
            [self.captureSession addInput:videoInput];
            self.activeVideoInput = videoInput;
        } else {
            [self.captureSession addInput:self.activeVideoInput];
        }
        [self.captureSession commitConfiguration];
    } else {
        return NO;
    }
    return YES;
}
复制代码

第五步:闪光灯,设置AVCaptureDevie的flashMode属性

AVCaptureDevice *device = [self activeCamera];

device.flashMode = flashMode;

第六步:聚焦,设置AVCaptureDevice的focusPointOfInterest属性

device.focusPointOfInterest = point;

device.focusMode = AVCaptureFocusModeAutoFocus;

第七步:曝光,设置AVCaptureDevice的exposurePointOfInterest属性

device.exposurePointOfInterest = point;

device.exposureMode = AVCaptureExposureModeAutoExpose;

第八步:手电筒,设置AVCaptureDevice的AVCaptureTorchMode

device.torchMode = torchMode;

第九步:缩放,设置AVCaptureDevice的videoZoomFactor属性

device.videoZoomFactor = scale;

第十步:拍摄,调用AVCaptureStillImageOutput的如下方法

- (void)captureStillImageAsynchronouslyFromConnection:(AVCaptureConnection *)connection completionHandler:(void (^)(CMSampleBufferRef _Nullable imageDataSampleBuffer, NSError * _Nullable error))handler

第十一步:录制

开始录制

[self.movieOutput startRecordingToOutputFileURL:self.outputURL  recordingDelegate:self];

结束录制

[self.movieOutput stopRecording];

获取录制结果在AVCaptureFileOutputRecordingDelegate的如下方法

- (void)captureOutput:(AVCaptureFileOutput *)output didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL fromConnections:(NSArray<AVCaptureConnection *> *)connections error:(NSError *)error

猜你喜欢

转载自juejin.im/post/7086277554755076133