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];