//
//  ViewController.m
//  AVFoundationCameraRecording
//
//  Created by ZhuYi on 16/5/3.
//  Copyright © 2016年 DDP. All rights reserved.
//

#import "ViewController.h"
#import <AVFoundation/AVFoundation.h>
#import <AssetsLibrary/AssetsLibrary.h>
typedef void(^PropertyChangeBlock)(AVCaptureDevice *captureDevice);

@interface ViewController ()<AVCaptureFileOutputRecordingDelegate>{
    UIButton *takephotoButton;
    UIView *viewContainer;
}

@property (strong,nonatomic) AVCaptureSession *captureSession;//负责输入和输出设置之间的数据传递
@property (strong,nonatomic) AVCaptureDeviceInput *captureDeviceInput;//负责从AVCaptureDevice获得输入数据
@property (strong,nonatomic) AVCaptureMovieFileOutput *captureMovieFileOutput;//视频输出流
@property (strong,nonatomic) AVCaptureVideoPreviewLayer *captureVideoPreviewLayer;//相机拍摄预览图层
@property (assign,nonatomic) UIBackgroundTaskIdentifier backgroundTaskIdentifier;//后台任务标识

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    viewContainer = [[UIView alloc] initWithFrame:CGRectMake(, , self.view.frame.size.width, self.view.frame.size.height - )];
    [self.view addSubview:viewContainer];
    takephotoButton = [UIButton buttonWithType:UIButtonTypeCustom];
    takephotoButton.backgroundColor = [UIColor orangeColor];
    [takephotoButton addTarget:self action:@selector(takePhoto) forControlEvents:UIControlEventTouchUpInside];
    takephotoButton.frame = CGRectMake(, self.view.frame.size.height - , self.view.frame.size.width, );
    [self.view addSubview:takephotoButton];

    //初始化会话
    _captureSession=[[AVCaptureSession alloc]init];
    _captureSession.sessionPreset=AVCaptureSessionPreset1920x1080;

    //获得输入设备
    AVCaptureDevice *captureDevice=[self getCameraDeviceWithPosition:AVCaptureDevicePositionBack];//取得后置摄像头

    //添加一个音频输入设备
    AVCaptureDevice *audioCaptureDevice=[[AVCaptureDevice devicesWithMediaType:AVMediaTypeAudio] firstObject];

    NSError *error=nil;
    //根据输入设备初始化设备输入对象,用于获得输入数据
    _captureDeviceInput=[[AVCaptureDeviceInput alloc]initWithDevice:captureDevice error:&error];
    AVCaptureDeviceInput *audioCaptureDeviceInput=[[AVCaptureDeviceInput alloc]initWithDevice:audioCaptureDevice error:&error];

    //初始化设备输出对象,用于获得输出数据
    _captureMovieFileOutput=[[AVCaptureMovieFileOutput alloc]init];

    //将设备输入添加到会话中
    if ([_captureSession canAddInput:_captureDeviceInput]) {
        [_captureSession addInput:_captureDeviceInput];
        [_captureSession addInput:audioCaptureDeviceInput];
        AVCaptureConnection *captureConnection=[_captureMovieFileOutput connectionWithMediaType:AVMediaTypeVideo];
        if ([captureConnection isVideoStabilizationSupported ]) {
            captureConnection.preferredVideoStabilizationMode=AVCaptureVideoStabilizationModeAuto;
        }
    }

    //将设备输出添加到会话中
    if ([_captureSession canAddOutput:_captureMovieFileOutput]) {
        [_captureSession addOutput:_captureMovieFileOutput];
    }

    //创建视频预览层,用于实时展示摄像头状态
    _captureVideoPreviewLayer=[[AVCaptureVideoPreviewLayer alloc]initWithSession:self.captureSession];

    CALayer *layer=viewContainer.layer;
    layer.masksToBounds=YES;

    _captureVideoPreviewLayer.frame=layer.bounds;
    _captureVideoPreviewLayer.videoGravity=AVLayerVideoGravityResizeAspectFill;//填充模式
    //将视频预览层添加到界面中
    [layer addSublayer:_captureVideoPreviewLayer];
    [self.captureSession startRunning];
}

/**
 *  取得指定位置的摄像头
 *
 *  @param position 摄像头位置
 *
 *  @return 摄像头设备
 */
-(AVCaptureDevice *)getCameraDeviceWithPosition:(AVCaptureDevicePosition )position{
    NSArray *cameras= [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
    for (AVCaptureDevice *camera in cameras) {
        if ([camera position]==position) {
            return camera;
        }
    }
    return nil;
}

- (void)takePhoto{
    //根据设备输出获得连接
    AVCaptureConnection *captureConnection=[self.captureMovieFileOutput connectionWithMediaType:AVMediaTypeVideo];
    //根据连接取得设备输出的数据
    if (![self.captureMovieFileOutput isRecording]) {
        //预览图层和视频方向保持一致
        captureConnection.videoOrientation=[self.captureVideoPreviewLayer connection].videoOrientation;
        NSString *outputFielPath=[NSTemporaryDirectory() stringByAppendingString:@"myMovie.mov"];
        NSLog(@"save path is :%@",outputFielPath);
        NSURL *fileUrl=[NSURL fileURLWithPath:outputFielPath];
        NSLog(@"fileUrl:%@",fileUrl);
        [self.captureMovieFileOutput startRecordingToOutputFileURL:fileUrl recordingDelegate:self];
    }
    else{
        [self.captureMovieFileOutput stopRecording];//停止录制
    }
}
-(void)captureOutput:(AVCaptureFileOutput *)captureOutput didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL fromConnections:(NSArray *)connections error:(NSError *)error{
    NSLog(@"视频录制完成.");
    //视频录入完成之后在后台将视频存储到相簿
    UIBackgroundTaskIdentifier lastBackgroundTaskIdentifier=self.backgroundTaskIdentifier;
    self.backgroundTaskIdentifier=UIBackgroundTaskInvalid;
    ALAssetsLibrary *assetsLibrary=[[ALAssetsLibrary alloc]init];
    [assetsLibrary writeVideoAtPathToSavedPhotosAlbum:outputFileURL completionBlock:^(NSURL *assetURL, NSError *error) {
        if (error) {
            NSLog(@"保存视频到相簿过程中发生错误,错误信息:%@",error.localizedDescription);
        }
        NSLog(@"outputUrl:%@",outputFileURL);
        [[NSFileManager defaultManager] removeItemAtURL:outputFileURL error:nil];
        if (lastBackgroundTaskIdentifier!=UIBackgroundTaskInvalid) {
            [[UIApplication sharedApplication] endBackgroundTask:lastBackgroundTaskIdentifier];
        }
        NSLog(@"成功保存视频到相簿.");
    }];
}
@end

AVFoundation--视频录制的更多相关文章

  1. AVFoundation自定义录制视频

    #import <AVFoundation/AVFoundation.h> #import <AssetsLibrary/AssetsLibrary.h> @interface ...

  2. iOS开发系列--音频播放、录音、视频播放、拍照、视频录制

    --iOS多媒体 概览 随着移动互联网的发展,如今的手机早已不是打电话.发短信那么简单了,播放音乐.视频.录音.拍照等都是很常用的功能.在iOS中对于多媒体的支持是非常强大的,无论是音视频播放.录制, ...

  3. IOS开发之小实例--创建一个简单的用于视频录制和回放的应用程序

    前言:还是看了一下国外的入门IOS文章:<Create a Simple App for Video Recording and Playback>,主要涉及视频录制和回放的功能的基本实现 ...

  4. iOS开发----音频播放、录音、视频播放、拍照、视频录制

    随着移动互联网的发展,如今的手机早已不是打电话.发短信那么简单了,播放音乐.视频.录音.拍照等都是很常用的功能.在iOS中对于多媒体的支持是非常强大的,无论是音视频播放.录制,还是对麦克风.摄像头的操 ...

  5. 音频播放、录音、视频播放、拍照、视频录制-b

    随着移动互联网的发展,如今的手机早已不是打电话.发短信那么简单了,播放音乐.视频.录音.拍照等都是很常用的功能.在iOS中对于多媒体的支持是非常强大的,无论是音视频播放.录制,还是对麦克风.摄像头的操 ...

  6. iOS音频播放、录音、视频播放、拍照、视频录制

    随着移动互联网的发展,如今的手机早已不是打电话.发短信那么简单了,播放音乐.视频.录音.拍照等都是很常用的功能.在iOS中对于多媒体的支持是非常强大的,无论是音视频播放.录制,还是对麦克风.摄像头的操 ...

  7. AVAudioFoundation(4):音视频录制

    本文转自:AVAudioFoundation(4):音视频录制 | www.samirchen.com 本文主要内容来自 AVFoundation Programming Guide. 采集设备的音视 ...

  8. github视频录制播放相关功能-参考

    lookingstars/JZVideoDemo  视频播放器 Updated on 11 Aug Objective-C 15 10 caoguoqing/VideoEditDemo  iOS vi ...

  9. android 视频录制 混淆打包 之native层 异常的解决

    原文地址:http://www.cnblogs.com/linguanh/    (滑至文章末,直接看解决方法) 问题起因: 前5天,因为项目里面有个类似 仿微信 视频录制的功能, 先是上网找了个 开 ...

  10. Android音视频之MediaRecorder音视频录制

    前言: 公司产品有很多地方都需要上传音频视频,今天抽空总结一下音频视频的录制.学习的主角是MediaRecorder类. MediaRecorder类介绍: MediaRecorder类是Androi ...

随机推荐

  1. C语言调用lua

    在lua API中,调用一个函数的步骤很简单: 1.压入你要调用的函数,使用lua_getglobal. 2.压入调用参数. 3.使用lua_pcall 4.从栈中弹出结果.   举例说明,假设你有这 ...

  2. nginx 配置访问限制

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px "Helvetica Neue"; color: #454545 } p. ...

  3. 目标检测中proposal的意义

    在目标检测中,从很早就有候选区域的说法,也是在2008年可能就有人使用这个方法,在2014年的卷积神经网络解决目标检测问题的文章中,这个候选框方法大放异彩,先前的目标检测方法主要集中在使用滑动窗口的方 ...

  4. python reduce使用实例

    通过一个简单的算法来了解reduce的巧用. 构建函数persistence(n),如果n>9,则返回0.否则继续根据n的权重来分解n,如n=999,则分解为9,9,9.那么将9*9*9=729 ...

  5. bitcode 关于讯飞

    在真机调试的时候一直报 ld: '/Users/Chenglijuan/Documents/语音识别/lib/iflyMSC.framework/iflyMSC(IFlyRecognizerView. ...

  6. edittext设置为密文显示

    et_msg.setInputType(InputType.TYPE_CLASS_TEXT |InputType.TYPE_TEXT_VARIATION_PASSWORD);

  7. 日期的本质是double

    日期的本质是double,在多语种时用起来更方便.

  8. maven中在本地maven仓库添加jar包

    Maven 手动添加 JAR 包到本地仓库 Maven 确确实实是个好东西,用来管理项目显得很方便,但是如果是通过 Maven 来远程下载 JAR 包的话,我宿舍的带宽是4兆的,4个人共用,有时候用  ...

  9. dplyr 数据操作 常用函数(2)

    继上一节常用函数,继续了解其他函数 1.desc() 这个函数和SQL中的排序用法是一样的,表示对数据进行倒序排序. 接下来我们看些例子. a=sample(20,50,rep=T)a desc(a) ...

  10. CentOS 7中将Tomcat设置为系统服务

    tomcat 需要增加一个pid文件,在tomca/bin 目录下面,增加 setenv.sh 配置,catalina.sh启动的时候会调用,在该文件中添加如下内容 CATALINA_PID=&quo ...