#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];

}

}];

}

AVFoundation自定义录制视频的更多相关文章

  1. Android自定义view之仿微信录制视频按钮

    本文章只写了个类似微信的录制视频的按钮,效果图如下:             一.主要的功能: 1.长按显示进度条,单击事件,录制完成回调 2.最大时间和最小时间控制 3.进度条宽度,颜色设置 二.实 ...

  2. iOS 三种录制视频方式

    随着每一代 iPhone 处理能力和相机硬件配置的提高,使用它来捕获视频也变得更加有意思.它们小巧,轻便,低调,而且与专业摄像机之间的差距已经变得非常小,小到在某些情况下,iPhone 可以真正替代它 ...

  3. 根据分析查看相关知识点分析iOS 三种录制视频方式

    这篇文章讨论了关于如何配置视频捕获管线 (pipeline) 和最大限度地利用硬件性能的一些不同选择. 这里有个使用了不同管线的样例 app,可以在 GitHub 查看. 第一种:UIImagePic ...

  4. iOS录制视频

    随着每一代 iPhone 处理能力和相机硬件配置的提高,使用它来捕获视频也变得更加有意思.它们小巧,轻便,低调,而且与专业摄像机之间的差距已经变得非常小,小到在某些情况下,iPhone 可以真正替代它 ...

  5. iOS AVCaptureVideoDataOutputSampleBufferDelegate 录制视频

    iOS AVCaptureVideoDataOutputSampleBufferDelegate 录制视频 应用场景: 使用AVFoundation提供的API, 我们可以从 AVCaptureVid ...

  6. 3D图片采集与展示(SurfaceView 自适应 Camera, 录制视频, 抽取帧)

    最近在做一个3D图片采集与展示. 主要功能为:自定义Camera(google 已经摈弃了Camera, 推荐使用Camera2,后续篇幅,我将会用Camera2取代Camera),围绕一个物体360 ...

  7. iOS 录制视频MOV格式转MP4

    使用UIImagePickerController系统控制器录制视频时,默认生成的格式是MOV,如果要转成MP4格式的,我们需要使用AVAssetExportSession; 支持转换的视频质量:低, ...

  8. bandicam如何录制视频

    我们一般都很熟悉这类软件:屏幕录制专家和kk录制等,这些都是国内比较优秀的作品.不过exe的封装格式以及录制的清晰度让人很纠结.所以这里要为大家分享的是一款韩国人写录制软件Bandicam.Bandi ...

  9. Android手机录制视频 实时传输(转载)

    最近调研android视频录制.另一部手机实时观看,大致有以下几种思路. 1. android手机充当服务器,使用NanoHTTPD充当服务器,另一部手机或者pc通过输入http://手机的ip:80 ...

随机推荐

  1. C++ 常量类型 const 详解

    1.什么是const? 常类型是指使用类型修饰符const说明的类型,常类型的变量或对象的值是不能被更新的.(当然,我们可以偷梁换柱进行更新:) 2.为什么引入const? const 推出的初始目的 ...

  2. Flex4 flash builder保留MXML转换的AS代码

    Flex4 flash builder保留MXML转换的AS代码 项目->属性->Flex编译器 | 附加的编译参数 加上 -keep 生成的Test005-interface.as文件: ...

  3. easyUI 添加排序到datagrid

    http://www.cnblogs.com/javaexam2/archive/2012/08/10/2632645.html

  4. JSP中使用Taglib

    http://blog.163.com/jany_1016/blog/static/4604400620091112114127341/ http://blog.csdn.net/yuebinghao ...

  5. Excel里函数中的万金油,你确定不要点进来看看?

    Excel里函数中的万金油,你确定不要点进来看看? 来源:EXCELHome Excel里有个号称"万能"的函数组合,这个函数组合就是INDEX+SMALL+IF,很多应用场合都能 ...

  6. SoapUI:使用Excel进行参数化

    本章中学习如下内容: 1)         使用DataSource调用Excel中的数据给接口参数化: 2)         使用DataSource Loop使得测试用例根据Excel中的取值循环 ...

  7. ABP入门系列(7)——分页实现

    ABP入门系列目录--学习Abp框架之实操演练 完成了任务清单的增删改查,咱们来讲一讲必不可少的的分页功能. 首先很庆幸ABP已经帮我们封装了分页实现,实在是贴心啊. 来来来,这一节咱们就来捋一捋如何 ...

  8. JDK1.8源码阅读系列之三:Vector

    本篇随笔主要描述的是我阅读 Vector 源码期间的对于 Vector 的一些实现上的个人理解,用于个人备忘,有不对的地方,请指出- 先来看一下 Vector 的继承图: 可以看出,Vector 的直 ...

  9. ubuntu下配置Apache

    ubuntu下配置Apache Apache的默认文档根目录是在Ubuntu上的/var/www目录 配置文件是/ etc/apache2/apache2.conf配置存储在的子目录在/etc/apa ...

  10. nRF51800 蓝牙学习 进程记录 1:感想

    一直想开一个高大上点的博客,觉得博客园不错,便申请了.一直没时间看,都快忘了,无意间登上提示申请到了.便写个东西看看. 正在学习nRF51822的蓝牙开发板,为了做毕设准备.备考中,一直没时间学,但今 ...