AVFoundation - Implementing a system camera

Please see Demo for the detailed code . Due to the large amount of code, only the key APIs are intercepted here.

Features we need to implement:

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

core classes used

AVCaptureDeviceaudio or video capture device

AVCaptureDeviceInputProvide media from capture device to capture session

AVCaptureSessionCapture sessions, manage capture activities and connect input to output data streams

AVCaptureStillImageOutputOutput still photos

AVCaptureMovieFileOutputOutput QuickTime video

Step 1: Initialize

1. Create an AVCaptureSession and set the quality

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

self.captureSession.sessionPreset = AVCaptureSessionPresetHigh;

2. Create video input device and capture media

AVCaptureDevice *videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];

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

3. Add video input capture media

[self.captureSession addInput:videoInput];

4. Create audio input device and capture media

AVCaptureDevice *audioDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];

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

5. Add audio input to capture media

[self.captureSession addInput:audioInput];

6. Create still photo output and join to current session

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

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

[self.captureSession addOutput:self.imageOutput];

7. Create video output and join to current session

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

[self.captureSession addOutput:self.movieOutput];

Step 2: Start a session

[self.captureSession startRunning];

Step 3: Create a preview layer and set up an AVCaptureSession session

AVCaptureVideoPreviewLayer *layer = [AVCaptureVideoPreviewLayer layer];

[layer setSession:session];

Step 4: Switch Cameras

Get the device opposite to the current active camera, get the corresponding capture media, remove the previous capture media, and add new capture media

- (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;
}
复制代码

Step 5: Flash, set the flashMode property of AVCaptureDevie

AVCaptureDevice *device = [self activeCamera];

device.flashMode = flashMode;

Step 6: Focus, set the focusPointOfInterest property of AVCaptureDevice

device.focusPointOfInterest = point;

device.focusMode = AVCaptureFocusModeAutoFocus;

Step 7: Exposure, set the exposurePointOfInterest property of AVCaptureDevice

device.exposurePointOfInterest = point;

device.exposureMode = AVCaptureExposureModeAutoExpose;

Step 8: Flashlight, set AVCaptureTorchMode of AVCaptureDevice

device.torchMode = torchMode;

Step 9: Zoom, set the videoZoomFactor property of AVCaptureDevice

device.videoZoomFactor = scale;

Step 10: Shoot, call the following method of AVCaptureStillImageOutput

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

Step 11: Record

start recording

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

end recording

[self.movieOutput stopRecording];

Get the recording result in the following method of AVCaptureFileOutputRecordingDelegate

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

Guess you like

Origin juejin.im/post/7086277554755076133