AVFoundation自定义录制视频

时间:2022-12-27 04:53:36

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

}

}];

}