iOS-摄像头切换,并获取录制数据(封装)

2023-03-28  本文已影响0人  温柔vs先生
//
//  CameraSessionManager.h
//  test
//
//  Created by wbb on 2023/3/24.
//

#import <Foundation/Foundation.h>
#import <AVFoundation/AVFoundation.h>
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN

@interface CameraSessionManager : NSObject <AVCaptureVideoDataOutputSampleBufferDelegate>

@property (nonatomic, strong) AVCaptureSession *session;
@property (nonatomic, strong) AVCaptureVideoPreviewLayer *previewLayer;
@property (nonatomic, strong) AVCaptureDeviceInput *videoInput;
@property (nonatomic, strong) AVCaptureVideoDataOutput *videoOutput;
@property (nonatomic, weak) UIView *previewView;

- (instancetype)initWithPreviewView:(UIView *)previewView;
- (void)startRunning;
- (void)stopRunning;
- (void)toggleCamera;
- (AVCaptureVideoPreviewLayer *)getPreviewLayer;

@end


NS_ASSUME_NONNULL_END

//
//  CameraSessionManager.m
//  test
//
//  Created by wbb on 2023/3/24.
//

#import "CameraSessionManager.h"

@implementation CameraSessionManager
- (instancetype)initWithPreviewView:(UIView *)previewView {
    self = [super init];
    if (self) {
        _previewView = previewView;
        _session = [[AVCaptureSession alloc] init];
        [self setupVideoInput];
        [self setupVideoOutput];
        [self setupPreviewLayer];
    }
    return self;
}

- (void)setupVideoInput {
    AVCaptureDevice *videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    NSError *error;
    _videoInput = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:&error];
    if (error) {
        // 错误处理
        return;
    }
    if ([self.session canAddInput:self.videoInput]) {
        [self.session addInput:self.videoInput];
    }
}

- (void)setupVideoOutput {
    _videoOutput = [[AVCaptureVideoDataOutput alloc] init];
    _videoOutput.videoSettings = @{(id)kCVPixelBufferPixelFormatTypeKey: @(kCVPixelFormatType_32BGRA)};
    _videoOutput.alwaysDiscardsLateVideoFrames = YES;
    dispatch_queue_t videoQueue = dispatch_queue_create("videoQueue", DISPATCH_QUEUE_SERIAL);
    [_videoOutput setSampleBufferDelegate:self queue:videoQueue];
    if ([self.session canAddOutput:self.videoOutput]) {
        [self.session addOutput:self.videoOutput];
    }
}

- (void)setupPreviewLayer {
    _previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.session];
    _previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
    _previewLayer.frame = self.previewView.bounds;
    [self.previewView.layer addSublayer:self.previewLayer];
}

- (void)startRunning {
//    [self.session startRunning];
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            [self.session startRunning];
        });
}

- (void)stopRunning {
    [self.session stopRunning];
}

- (void)toggleCamera {
    AVCaptureDevicePosition position = self.videoInput.device.position;
    AVCaptureDevice *newVideoDevice = nil;
    if (position == AVCaptureDevicePositionBack) {
        newVideoDevice = [self videoDeviceWithPosition:AVCaptureDevicePositionFront];
    } else {
        newVideoDevice = [self videoDeviceWithPosition:AVCaptureDevicePositionBack];
    }
    NSError *error;
    AVCaptureDeviceInput *newVideoInput = [AVCaptureDeviceInput deviceInputWithDevice:newVideoDevice error:&error];
    if (error) {
        // 错误处理
        return;
    }
    [self.session beginConfiguration];
    [self.session removeInput:self.videoInput];
    if ([self.session canAddInput:newVideoInput]) {
        [self.session addInput:newVideoInput];
        self.videoInput = newVideoInput;
    } else {
        [self.session addInput:self.videoInput];
    }
    [self.session commitConfiguration];
}

- (AVCaptureVideoPreviewLayer *)getPreviewLayer {
    return self.previewLayer;
}

- (AVCaptureDevice *)videoDeviceWithPosition:(AVCaptureDevicePosition)position {
    AVCaptureDeviceDiscoverySession *discoverySession = [AVCaptureDeviceDiscoverySession discoverySessionWithDeviceTypes:@[AVCaptureDeviceTypeBuiltInWideAngleCamera] mediaType:AVMediaTypeVideo position:AVCaptureDevicePositionUnspecified];
    NSArray *devices = discoverySession.devices;
    for (AVCaptureDevice *device in devices) {
        if (device.position == position) {
            return device;
        }
    }
    return nil;
}

- (void)captureOutput:(AVCaptureOutput *)output didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {
    // 处理视频帧数据
}
@end

使用:

    CameraSessionManager *manager = [[CameraSessionManager alloc] initWithPreviewView:self.view];
    [self.view.layer addSublayer:[manager getPreviewLayer]];
    self.manager = manager;
    [manager startRunning];
上一篇下一篇

猜你喜欢

热点阅读