美文网首页
iOS-摄像头切换,并获取录制数据(封装)

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

作者: 温柔vs先生 | 来源:发表于2023-03-28 20:06 被阅读0次
    //
    //  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];
    

    相关文章

      网友评论

          本文标题:iOS-摄像头切换,并获取录制数据(封装)

          本文链接:https://www.haomeiwen.com/subject/jajxddtx.html