视频录制-AVFoundation - (Obj-C)

视频录制与扫描二维码实现类似,区别在于:
录制视频需要捕获: 音频+视频 --> 生成一个视频文件

所以在声明输入设备时,需要一个视频输入设备和一个音频输入设备

// 输入设备 视频
@property (nonatomic,strong) AVCaptureDeviceInput *videoInput;
// 输入设备 音频
@property (nonatomic,strong) AVCaptureDeviceInput *audioInput;

其他属性

// 输出设备
@property (nonatomic,strong) AVCaptureMovieFileOutput *movieOutput;
// 会话
@property (nonatomic,strong) AVCaptureSession *session;
// 预览视图
@property (nonatomic,strong) AVCaptureVideoPreviewLayer *previewLayer;

注意点:
1.测试录制视频,需要使用真机进行
2.为了模拟效果,在视图控制器view上添加了开始录制按钮,当添加预览Layer时,如果直接添加到view的layer上,就会遮挡视图view上的按钮,所以使用了插入的方式

实例化属性,并将输入输出设备分别添加至会话中,并设置预览视图,将预览视图添加到视图上,最后开启会话,这样就可以调用摄像头,并将摄像头捕捉到的画面呈现在视图中

// 将录制Layer预览呈现在视图上
- (void)viewDidLoad {
    [super viewDidLoad];

    // 2. 输入设置
    /*          设置设备类型
     NSString *const AVMediaTypeVideo;
     NSString *const AVMediaTypeAudio;
     NSString *const AVMediaTypeText;
     NSString *const AVMediaTypeClosedCaption;
     NSString *const AVMediaTypeSubtitle;
     NSString *const AVMediaTypeTimecode;
     NSString *const AVMediaTypeTimedMetadata;
     NSString *const AVMediaTypeMetadata;
     NSString *const AVMediaTypeMuxed;
     
     */
    // 视频
    AVCaptureDevice *videoDevice= [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    self.videoInput = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:nil];
    // 音频
    AVCaptureDevice *audioDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];
    self.audioInput = [AVCaptureDeviceInput deviceInputWithDevice:audioDevice error:nil];
    
    // 3. 输出设备
    self.movieOutput = [[AVCaptureMovieFileOutput alloc] init];
    
    // 4. 会话
    self.session = [[AVCaptureSession alloc] init];
    
    // 添加输入输出设备
    if ([self.session canAddInput:self.audioInput]) {
        [self.session addInput:self.audioInput];
    }
    if ([self.session canAddInput:self.videoInput]) {
        [self.session addInput:self.videoInput];
    }
    if ([self.session canAddOutput:self.movieOutput]) {
        [self.session addOutput:self.movieOutput];
    }
    
    // 5. 预览视图
    self.previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.session];
    
    // 添加到视图中并且设置位置
    [self.view.layer insertSublayer:self.previewLayer atIndex:0]; // 如果直接添加到View上,Layer会遮挡View上的开始录制按钮,所以使用了插入
    self.previewLayer.frame = self.view.bounds;
    
    // 6. 开始会话
    [self.session startRunning];
    
}

录制视频通过代理的方式实现,需要遵循协议,设置代理并实现两个代理方法:

接下来,在开始录制按钮点击事件中

// 开始录制    录制视频 : 捕获 音频+视频 生成一个视频文件
- (IBAction)clickRecordButton:(id)sender {
    
    // 录制的视频文件存放路径
    NSString *filePath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) lastObject];
    NSURL *libraryUrl = [NSURL fileURLWithPath:filePath];
    NSURL *fileUrl = [libraryUrl URLByAppendingPathComponent:@"movie.mp4"];
    
    // 使用输出设备进行录制 (通过代理的方式)
    [self.movieOutput startRecordingToOutputFileURL:fileUrl recordingDelegate:self];
      
}

停止录制按钮点击事件中

// 停止录制
- (IBAction)clickStopRecordButton:(id)sender {
    [self.movieOutput stopRecording];
    
    // 停止后关闭摄像头(将预览layer从当前视图移除)
    [self.previewLayer removeFromSuperlayer];
}

当第一次运行时,会提示需要授权使用摄像头和麦克风:

视频录制-AVFoundation - (Obj-C)_第1张图片
camera.PNG
mic.PNG

虽然开始录制和完成录制的代理方法中还未做任何处理,实际当我点击开始录制按钮时,就已经开始了录制,点击完成录制按钮停止录制后,获取到手机真机沙盒可以看到文件已经生成:

录制视频.png

下一篇文章会对存放于沙盒中的录制视频做提取操作.

你可能感兴趣的:(视频录制-AVFoundation - (Obj-C))