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