美文网首页
AVFoundation实现拍照与录制

AVFoundation实现拍照与录制

作者: LoveToday2020 | 来源:发表于2020-06-28 19:39 被阅读0次

    有关AVFoundation的一些类

    1. 捕捉会话:AVCaptureSession.
      2.􏱽􏱾􏰗􏰘 捕捉设备:AVCaptureDevice.
      3.􏱽􏱾􏰗􏰘􏰪 􏰫捕捉设备输入:AVCaptureDeviceInput
      􏱽􏱾􏰗􏰘􏰪􏰳􏱽􏱾􏰗􏰘􏰪􏰳4. 捕捉设备输出: AVCaptureOutput 􏲅􏲆􏲇.
      a. AVCaptureStillImageOutput
      b. AVCaputureMovieFileOutput
      c. AVCaputureAudioDataOutput
      d. AVCaputureVideoDataOutput
    2. 捕捉连接
      AVCaptureConnection
    3. 捕捉预览
      AVCaptureVideoPreviewLayer

    案例1. 拍照
    设置会话

    - (BOOL)setupSession:(NSError **)error {
    
        
        //创建捕捉会话。AVCaptureSession 是捕捉场景的中心枢纽
        self.captureSession = [[AVCaptureSession alloc]init];
        
        /*
         AVCaptureSessionPresetHigh
         AVCaptureSessionPresetMedium
         AVCaptureSessionPresetLow
         AVCaptureSessionPreset640x480
         AVCaptureSessionPreset1280x720
         AVCaptureSessionPresetPhoto
         */
        //设置图像的分辨率
        self.captureSession.sessionPreset = AVCaptureSessionPresetHigh;
        
        //拿到默认视频捕捉设备 iOS系统返回后置摄像头
        AVCaptureDevice *videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
        
        //将捕捉设备封装成AVCaptureDeviceInput
        //注意:为会话添加捕捉设备,必须将设备封装成AVCaptureDeviceInput对象
        AVCaptureDeviceInput *videoInput = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:error];
        
        //判断videoInput是否有效
        if (videoInput)
        {
            //canAddInput:测试是否能被添加到会话中
            if ([self.captureSession canAddInput:videoInput])
            {
                //将videoInput 添加到 captureSession中
                [self.captureSession addInput:videoInput];
                self.activeVideoInput = videoInput;
            }
        }else
        {
            return NO;
        }
        
    
    
        //AVCaptureStillImageOutput 实例 从摄像头捕捉图片
        self.imageOutput = [[AVCapturePhotoOutput alloc]init];
        
        //输出连接 判断是否可用,可用则添加到输出连接中去
        if ([self.captureSession canAddOutput:self.imageOutput])
        {
            [self.captureSession addOutput:self.imageOutput];
            
        }
        
        self.videoQueue = dispatch_queue_create("test.VideoQueue", NULL);
        
        return YES;
    }
    

    开始与结束会话

    - (void)startSession {
    
        //检查是否处于运行状态
        if (![self.captureSession isRunning])
        {
            //使用同步调用会损耗一定的时间,则用异步的方式处理
            dispatch_async(self.videoQueue, ^{
                [self.captureSession startRunning];
            });
            
        }
    }
    
    - (void)stopSession {
        
        //检查是否处于运行状态
        if ([self.captureSession isRunning])
        {
            //使用异步方式,停止运行
            dispatch_async(self.videoQueue, ^{
                [self.captureSession stopRunning];
            });
        }
        
    
    
    }
    

    预览(也就是显示)

    - (void)loadView{
        self.view = self.previewView;
    }
    #import "VFPreviewView.h"
    #import <AVFoundation/AVFoundation.h>
    
    @implementation VFPreviewView
    
    + (Class)layerClass{
        return [AVCaptureVideoPreviewLayer class];
    }
    
    @end
    

    获取设备方向

    //获取方向值
    - (AVCaptureVideoOrientation)currentVideoOrientation {
        
        AVCaptureVideoOrientation orientation;
        
        //获取UIDevice 的 orientation
        switch ([UIDevice currentDevice].orientation) {
            case UIDeviceOrientationPortrait:
                orientation = AVCaptureVideoOrientationPortrait;
                break;
            case UIDeviceOrientationLandscapeRight:
                orientation = AVCaptureVideoOrientationLandscapeLeft;
                break;
            case UIDeviceOrientationPortraitUpsideDown:
                orientation = AVCaptureVideoOrientationPortraitUpsideDown;
                break;
            default:
                orientation = AVCaptureVideoOrientationLandscapeRight;
                break;
        }
        
        return orientation;
    
        return 0;
    }
    

    采集信息

    - (void)captureOutput:(AVCapturePhotoOutput *)captureOutput didFinishProcessingPhotoSampleBuffer:(nullable CMSampleBufferRef)photoSampleBuffer previewPhotoSampleBuffer:(nullable CMSampleBufferRef)previewPhotoSampleBuffer resolvedSettings:(AVCaptureResolvedPhotoSettings *)resolvedSettings bracketSettings:(nullable AVCaptureBracketedStillImageSettings *)bracketSettings error:(nullable NSError *)error {
        
        NSData *data = [AVCapturePhotoOutput JPEGPhotoDataRepresentationForJPEGSampleBuffer:photoSampleBuffer previewPhotoSampleBuffer:previewPhotoSampleBuffer];
        UIImage *image = [UIImage imageWithData:data];
        
        [self writeImageToAssetsLibrary:image];
    }
    

    案例2: 录制视频
    预览跟拍照完全一致
    1.设置会话

    - (BOOL)setupSession:(NSError **)error {
        //创建捕捉会话。AVCaptureSession 是捕捉场景的中心枢纽
        self.captureSession = [[AVCaptureSession alloc]init];
        /*
         AVCaptureSessionPresetHigh
         AVCaptureSessionPresetMedium
         AVCaptureSessionPresetLow
         AVCaptureSessionPreset640x480
         AVCaptureSessionPreset1280x720
         AVCaptureSessionPresetPhoto
         */
        //设置图像的分辨率
        self.captureSession.sessionPreset = AVCaptureSessionPresetHigh;
        
        //拿到默认视频捕捉设备 iOS系统返回后置摄像头
        AVCaptureDevice *videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
        
        //将捕捉设备封装成AVCaptureDeviceInput
        //注意:为会话添加捕捉设备,必须将设备封装成AVCaptureDeviceInput对象
        AVCaptureDeviceInput *videoInput = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:error];
        //判断videoInput是否有效
        if (videoInput)
        {
            //canAddInput:测试是否能被添加到会话中
            if ([self.captureSession canAddInput:videoInput])
            {
                //将videoInput 添加到 captureSession中
                [self.captureSession addInput:videoInput];
                self.activeVideoInput = videoInput;
            }
        }else
        {
            return NO;
        }
        
        //选择默认音频捕捉设备 即返回一个内置麦克风
        AVCaptureDevice *audioDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];
        
        //为这个设备创建一个捕捉设备输入
        AVCaptureDeviceInput *audioInput = [AVCaptureDeviceInput deviceInputWithDevice:audioDevice error:error];
       
        //判断audioInput是否有效
        if (audioInput) {
            
            //canAddInput:测试是否能被添加到会话中
            if ([self.captureSession canAddInput:audioInput])
            {
                //将audioInput 添加到 captureSession中
                [self.captureSession addInput:audioInput];
            }
        }else
        {
            return NO;
        }
    
        //创建一个AVCaptureMovieFileOutput 实例,用于将Quick Time 电影录制到文件系统
        self.movieOutput = [[AVCaptureMovieFileOutput alloc]init];
        
        //输出连接 判断是否可用,可用则添加到输出连接中去
        if ([self.captureSession canAddOutput:self.movieOutput])
        {
            [self.captureSession addOutput:self.movieOutput];
        }
        
        
        self.videoQueue = dispatch_queue_create("test.VideoQueue", NULL);
        return YES;
    }
    

    2.判断是否录制状态

    - (BOOL)isRecording {
    
        return self.movieOutput.isRecording;
    }
    

    3.开始录制

    - (void)startRecording {
    
        if (![self isRecording]) {
            
            //获取当前视频捕捉连接信息,用于捕捉视频数据配置一些核心属性
            AVCaptureConnection * videoConnection = [self.movieOutput connectionWithMediaType:AVMediaTypeVideo];
            
            //判断是否支持设置videoOrientation 属性。
            if([videoConnection isVideoOrientationSupported])
            {
                //支持则修改当前视频的方向
                videoConnection.videoOrientation = [self currentVideoOrientation];
                
            }
            
            //判断是否支持视频稳定 可以显著提高视频的质量。只会在录制视频文件涉及
            if([videoConnection isVideoStabilizationSupported])
            {
                videoConnection.enablesVideoStabilizationWhenAvailable = YES;
            }
            
            
            AVCaptureDevice *device = self.activeVideoInput.device;
            
            //摄像头可以进行平滑对焦模式操作。即减慢摄像头镜头对焦速度。当用户移动拍摄时摄像头会尝试快速自动对焦。
            if (device.isSmoothAutoFocusEnabled) {
                NSError *error;
                if ([device lockForConfiguration:&error]) {
                    
                    device.smoothAutoFocusEnabled = YES;
                    [device unlockForConfiguration];
                }else
                {
                    NSLog(@"失败");
                }
            }
            
            //查找写入捕捉视频的唯一文件系统URL.
            self.outputURL = [self uniqueURL];
            
            //在捕捉输出上调用方法 参数1:录制保存路径  参数2:代理
            [self.movieOutput startRecordingToOutputFileURL:self.outputURL recordingDelegate:self];
            
        }
        
        
    }
    

    录制视频采集

    #pragma mark - AVCaptureFileOutputRecordingDelegate
    
    - (void)captureOutput:(AVCaptureFileOutput *)captureOutput
    didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL
          fromConnections:(NSArray *)connections
                    error:(NSError *)error {
    
        //错误
        if (error) {
            NSLog(@"失败");
        }else
        {
            //写入
            [self writeVideoToAssetsLibrary:[self.outputURL copy]];
            
        }
        
        self.outputURL = nil;
        
    
    }
    

    最后送上github地址

    https://github.com/LoveToday/AVFoundation_VideoAndPhoto.git

    相关文章

      网友评论

          本文标题:AVFoundation实现拍照与录制

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