• AVFoundation自定义录制视频


    #import <AVFoundation/AVFoundation.h>

    #import <AssetsLibrary/AssetsLibrary.h>

     

    @interface ViewController ()<AVCaptureFileOutputRecordingDelegate>

     

    @property(nonatomic,strong)AVCaptureSession *session;

    @property(nonatomic,strong)AVCaptureDevice *videoDevice;

    @property(nonatomic,strong)AVCaptureDevice *audioDevice;

    @property(nonatomic,strong)AVCaptureDeviceInput *videoInput;

    @property(nonatomic,strong)AVCaptureDeviceInput *audioInput;

    @property(nonatomic,strong)AVCaptureMovieFileOutput *movieFileOutput;

    @property(nonatomic,strong)AVCaptureVideoPreviewLayer *videoLayer;

     

    @property(nonatomic,assign)UIBackgroundTaskIdentifier backgroundTaskIdentifier;

    @property (weak, nonatomic) IBOutlet UIButton *RecordButton;

     @end

     @implementation ViewController

     

    - (void)viewWillAppear:(BOOL)animated{

        [super viewWillAppear:animated];

        

          [self initWithSession];

        

    }

    - (void)viewDidAppear:(BOOL)animated{

        [super viewDidAppear:animated];

        

        [self.session startRunning];

    }

    - (void)viewWillDisappear:(BOOL)animated{

        [super viewWillDisappear:animated];

        

        [self.session stopRunning];

    }

     

    - (void)viewDidLoad {

        [super viewDidLoad];

        self.view.backgroundColor = [UIColor orangeColor];

    }

     

    #pragma mark  -初始化

    - (void)initWithSession{

        _session = [[AVCaptureSession alloc]init];

        if ([_session canSetSessionPreset:AVCaptureSessionPreset1280x720]) {

            [_session setSessionPreset:AVCaptureSessionPreset1280x720];

        }

        NSArray *deviceArray = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];

        for (AVCaptureDevice *device in deviceArray) {

            if (device.position == AVCaptureDevicePositionBack) {

                _videoDevice = device;

            }

        }

        _audioDevice = [[AVCaptureDevice devicesWithMediaType:AVMediaTypeAudio]firstObject];

        NSError *error = nil;

        _videoInput = [[AVCaptureDeviceInput alloc]initWithDevice:_videoDevice error:&error];

        _audioInput = [[AVCaptureDeviceInput alloc]initWithDevice:_audioDevice error:&error];

        if ([_session canAddInput:_videoInput]) {

            [_session addInput:_videoInput];

        }

        if ([_session canAddInput:_audioInput]) {

            [_session addInput:_audioInput];

        }

        _movieFileOutput = [[AVCaptureMovieFileOutput alloc]init];

        if ([_session canAddOutput:_movieFileOutput]) {

            [_session addOutput:_movieFileOutput];

        }

        AVCaptureConnection *connection = [_movieFileOutput connectionWithMediaType:AVMediaTypeVideo];

        //此处是为了设置视频防抖动在iOS8以后才有,需要加系统判断

        if ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0){

         if ([connection isVideoStabilizationSupported]) {

            connection.preferredVideoStabilizationMode = AVCaptureVideoStabilizationModeCinematic;//iOS8以后才有效,要加判断

         }

        }

        _videoLayer = [AVCaptureVideoPreviewLayer layerWithSession:_session];

        _videoLayer.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 500);

        self.view.layer.masksToBounds = YES;

        _videoLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;

        [self.view.layer addSublayer:_videoLayer];

        

        _RecordButton.selected = NO;

     

    }

     

    #pragma mark  --当 拍摄 按钮点击

    - (IBAction)takePhoto:(id)sender {

        _RecordButton.selected = !_RecordButton.selected; //改变按钮状态切换上面文字

        AVCaptureConnection *captureConnection = [self.movieFileOutput connectionWithMediaType:AVMediaTypeVideo];

        if (![self.movieFileOutput isRecording]) {

            //如果支持多任务则开始多任务

            if ([[UIDevice currentDevice] isMultitaskingSupported]) {

                self.backgroundTaskIdentifier = [[UIApplication sharedApplication]beginBackgroundTaskWithExpirationHandler:nil];

            }

            //预览层和视频方向保持一致

            captureConnection.videoOrientation = [self.videoLayer connection].videoOrientation;

            //建立录制缓存文件

            NSString *outputFilePath = [NSTemporaryDirectory() stringByAppendingString:@"mMovie.mov"];

            NSURL *fileUrl = [NSURL fileURLWithPath:outputFilePath];

            //此句是为了开始录制,并设置代理

            [self.movieFileOutput  startRecordingToOutputFileURL:fileUrl recordingDelegate:self];

        }

        else

        {

            [self.movieFileOutput stopRecording];

        }

     

    }

     

    #pragma mark 视频输出代理

    - (void)captureOutput:(AVCaptureFileOutput *)captureOutput didStartRecordingToOutputFileAtURL:(NSURL *)fileURL fromConnections:(NSArray *)connections

    {

        NSLog(@"开始录制");

    }

     

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

    {

        NSLog(@"视频录制完成");

        UIBackgroundTaskIdentifier lastBackgroundTaskIdentifier = self.backgroundTaskIdentifier;

        self.backgroundTaskIdentifier = UIBackgroundTaskInvalid;

        ALAssetsLibrary *assetLibrary = [[ALAssetsLibrary alloc]init];

        

        [assetLibrary writeVideoAtPathToSavedPhotosAlbum:outputFileURL completionBlock:^(NSURL *assetURL, NSError *error) {

            if (error) {

                NSLog(@"保存视频到相薄发生错误");

            }

            if(lastBackgroundTaskIdentifier != UIBackgroundTaskInvalid)

            {

                [[UIApplication sharedApplication]endBackgroundTask:lastBackgroundTaskIdentifier];

            }

            NSLog(@"成功保存视频到相薄");

            NSString *outputFilePath = [NSTemporaryDirectory() stringByAppendingString:@"mMovie.mov"];

            if ([[NSFileManager defaultManager] fileExistsAtPath:outputFilePath]) {

                [[NSFileManager defaultManager]removeItemAtPath:outputFilePath error:nil];

            }

        }];

        

        

    }

  • 相关阅读:
    解决beego运行程序报错问题:stderr: go: github.com/astaxie/beego@v1.12.1: missing go.sum entry
    Flutter-填平菜鸟和高手之间的沟壑
    百度地图的脑残设计,附上代码,为后来的码农们...
    迅捷Flutter图片浏览软件
    青峰Flutter视频播放软件
    Element UI 自定义Validator
    在C#中如何URL编码和解码
    Postman新手入门
    安装SSDT2017
    layer.prompt 输入值为空的时候点击confirm不能继续
  • 原文地址:https://www.cnblogs.com/daxueshan/p/5852351.html
Copyright © 2020-2023  润新知