您好,登錄后才能下訂單哦!
本篇文章給大家分享的是有關(guān)怎么在iOS中使用AVCaptureSession實(shí)現(xiàn)視頻錄制功能,小編覺(jué)得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話(huà)不多說(shuō),跟著小編一起來(lái)看看吧。
具體內(nèi)容如下
#import "RecordingVideoViewController.h" #import <AVFoundation/AVFoundation.h> #import <AssetsLibrary/AssetsLibrary.h> @interface RecordingVideoViewController ()<AVCaptureFileOutputRecordingDelegate> //會(huì)話(huà) 負(fù)責(zé)輸入和輸出設(shè)備之間的數(shù)據(jù)傳遞 @property (strong,nonatomic) AVCaptureSession *captureSession; //設(shè)備輸入 負(fù)責(zé)從AVCaptureDevice獲得輸入數(shù)據(jù) @property (strong,nonatomic) AVCaptureDeviceInput *videoCaptureDeviceInput; @property (strong,nonatomic) AVCaptureDeviceInput *audioCaptureDeviceInput; //視頻輸出流 @property (strong,nonatomic) AVCaptureMovieFileOutput *captureMovieFileOutput; //相機(jī)拍攝預(yù)覽圖層 @property (strong,nonatomic) AVCaptureVideoPreviewLayer *captureVideoPreviewLayer; //自定義UI控件容器 @property (strong,nonatomic) UIView *viewContainer; //聚焦圖標(biāo) @property (strong,nonatomic) UIImageView *focusCursor; //錄制時(shí)長(zhǎng) @property (strong,nonatomic) UILabel *timeLabel; //切換前后攝像頭 @property (strong,nonatomic) UIButton *switchCameraBtn; //改變焦距 @property (strong,nonatomic) UIButton *scaleBtn; //計(jì)時(shí)器 @property (strong,nonatomic) NSTimer *timer; @end @implementation RecordingVideoViewController { @private NSInteger _num; CGFloat _kCameraScale; } - (UIView *)viewContainer { if (!_viewContainer) { _viewContainer = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds]; UIButton *takeButton = [UIButton buttonWithType:UIButtonTypeCustom]; takeButton.backgroundColor = [UIColor redColor]; [takeButton setTitle:@"start" forState:UIControlStateNormal]; [takeButton addTarget:self action:@selector(takeButtonClick:) forControlEvents:UIControlEventTouchUpInside]; _timeLabel = [[UILabel alloc] init]; _timeLabel.textColor = [UIColor redColor]; _timeLabel.textAlignment = NSTextAlignmentCenter; _timeLabel.font = [UIFont boldSystemFontOfSize:20]; _timeLabel.text = @"00:00"; _switchCameraBtn = [UIButton buttonWithType:UIButtonTypeCustom]; [_switchCameraBtn setTitle:@"switch" forState:UIControlStateNormal]; _switchCameraBtn.backgroundColor = [UIColor redColor]; [_switchCameraBtn addTarget:self action:@selector(switchCameraBtnClick) forControlEvents:UIControlEventTouchUpInside]; _scaleBtn = [UIButton buttonWithType:UIButtonTypeCustom]; [_scaleBtn setTitle:@"1X" forState:UIControlStateNormal]; _scaleBtn.backgroundColor = [UIColor redColor]; [_scaleBtn addTarget:self action:@selector(scaleBtnClick:) forControlEvents:UIControlEventTouchUpInside]; [_viewContainer addSubview:takeButton]; [_viewContainer addSubview:_timeLabel]; [_viewContainer addSubview:_scaleBtn]; [_viewContainer addSubview:_switchCameraBtn]; [takeButton mas_makeConstraints:^(MASConstraintMaker *make) { make.size.mas_equalTo(CGSizeMake(60, 40)); make.centerX.mas_equalTo(_viewContainer); make.bottom.mas_equalTo(_viewContainer).offset(-64); }]; [_timeLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.centerX.mas_equalTo(_viewContainer); make.height.mas_equalTo(@30); make.top.mas_equalTo(_viewContainer); }]; [_scaleBtn mas_makeConstraints:^(MASConstraintMaker *make) { make.size.mas_equalTo(CGSizeMake(60, 40)); make.left.mas_equalTo(_viewContainer).offset(10); make.top.mas_equalTo(_viewContainer); }]; [_switchCameraBtn mas_makeConstraints:^(MASConstraintMaker *make) { make.size.mas_equalTo(CGSizeMake(60, 40)); make.top.mas_equalTo(_viewContainer); make.right.mas_equalTo(_viewContainer).offset(-10); }]; _focusCursor = [[UIImageView alloc] init]; kBorder(_focusCursor, 1, [UIColor yellowColor]); _focusCursor.alpha = 0; [_viewContainer addSubview:self.focusCursor]; [_focusCursor mas_makeConstraints:^(MASConstraintMaker *make) { make.size.mas_equalTo(CGSizeMake(40, 40)); make.center.mas_equalTo(_viewContainer); }]; } return _viewContainer; } - (void)viewDidLoad { [super viewDidLoad]; self.title = @"視頻錄制"; _kCameraScale = 1.0f; //初始化會(huì)話(huà)對(duì)象 _captureSession = [[AVCaptureSession alloc] init]; if ([_captureSession canSetSessionPreset:AVCaptureSessionPreset1280x720]) { _captureSession.sessionPreset = AVCaptureSessionPreset1280x720; } NSError *error = nil; //獲取視頻輸入對(duì)象 AVCaptureDevice *videoCaptureDevice = [self cameraDeviceWithPosition:(AVCaptureDevicePositionBack)]; if (!videoCaptureDevice) { NSLog(@"獲取后置攝像頭失敗!"); return; } _videoCaptureDeviceInput = [[AVCaptureDeviceInput alloc] initWithDevice:videoCaptureDevice error:&error]; if (error) { NSLog(@"取得視頻設(shè)備輸入對(duì)象時(shí)出錯(cuò)"); return; } //獲取音頻輸入對(duì)象 AVCaptureDevice *audioCatureDevice = [[AVCaptureDevice devicesWithMediaType:AVMediaTypeAudio] firstObject]; _audioCaptureDeviceInput = [[AVCaptureDeviceInput alloc] initWithDevice:audioCatureDevice error:&error]; if (error) { NSLog(@"取得音頻設(shè)備輸入對(duì)象時(shí)出錯(cuò)"); return; } //初始化設(shè)備輸出對(duì)象 _captureMovieFileOutput = [[AVCaptureMovieFileOutput alloc] init]; //將設(shè)備輸入添加到會(huì)話(huà)中 if ([_captureSession canAddInput:_videoCaptureDeviceInput]) { [_captureSession addInput:_videoCaptureDeviceInput]; [_captureSession addInput:_audioCaptureDeviceInput]; //防抖功能 AVCaptureConnection *captureConnection = [_captureMovieFileOutput connectionWithMediaType:AVMediaTypeAudio]; if ([captureConnection isVideoStabilizationSupported]) { captureConnection.preferredVideoStabilizationMode = AVCaptureVideoStabilizationModeAuto; } } //將設(shè)備輸出添加到會(huì)話(huà)中 if ([_captureSession canAddOutput:_captureMovieFileOutput]) { [_captureSession addOutput:_captureMovieFileOutput]; } //創(chuàng)建視頻預(yù)覽圖層 _captureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:_captureSession]; self.viewContainer.layer.masksToBounds = YES; _captureVideoPreviewLayer.frame = self.viewContainer.bounds; _captureVideoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill; [self.view.layer addSublayer:_captureVideoPreviewLayer]; //顯示自定義控件 [self.view addSubview:self.viewContainer]; //添加點(diǎn)按聚焦手勢(shì) UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapScreen:)]; [self.viewContainer addGestureRecognizer:tapGesture]; } -(void)viewDidAppear:(BOOL)animated{ [super viewDidAppear:animated]; [self.captureSession startRunning]; } -(void)viewDidDisappear:(BOOL)animated{ [super viewDidDisappear:animated]; [self.captureSession stopRunning]; [self.timer invalidate]; self.timer = nil; } - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; [self.captureVideoPreviewLayer setAffineTransform:CGAffineTransformMakeScale(1, 1)]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; } //開(kāi)始 + 暫停錄制 - (void)takeButtonClick:(UIButton *)sender { if ([self.captureMovieFileOutput isRecording]) { [self.captureMovieFileOutput stopRecording]; [self.navigationController popViewControllerAnimated:YES]; } else { AVCaptureConnection *captureConnection = [self.captureMovieFileOutput connectionWithMediaType:AVMediaTypeVideo]; captureConnection.videoOrientation = [self.captureVideoPreviewLayer connection].videoOrientation; NSString *filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"Movie.mov"]; NSLog(@"%@",filePath); [self.captureMovieFileOutput startRecordingToOutputFileURL:[NSURL fileURLWithPath:filePath] recordingDelegate:self]; self.switchCameraBtn.hidden = YES; sender.backgroundColor = [UIColor greenColor]; [sender setTitle:@"stop" forState:UIControlStateNormal]; self.timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timeAction) userInfo:nil repeats:YES]; [self.timer setFireDate:[NSDate distantPast]]; } } //切換攝像頭 - (void)switchCameraBtnClick { AVCaptureDevicePosition currentPosition = self.videoCaptureDeviceInput.device.position; AVCaptureDevicePosition toPosition; if (currentPosition == AVCaptureDevicePositionUnspecified || currentPosition == AVCaptureDevicePositionFront) { toPosition = AVCaptureDevicePositionBack; } else { toPosition = AVCaptureDevicePositionFront; } AVCaptureDevice *toCapturDevice = [self cameraDeviceWithPosition:toPosition]; if (!toCapturDevice) { NSLog(@"獲取要切換的設(shè)備失敗"); return; } NSError *error = nil; AVCaptureDeviceInput *toVideoDeviceInput = [[AVCaptureDeviceInput alloc] initWithDevice:toCapturDevice error:&error]; if (error) { NSLog(@"獲取要切換的設(shè)備輸入失敗"); return; } //改變會(huì)話(huà)配置 [self.captureSession beginConfiguration]; [self.captureSession removeInput:self.videoCaptureDeviceInput]; if ([self.captureSession canAddInput:toVideoDeviceInput]) { [self.captureSession addInput:toVideoDeviceInput]; self.videoCaptureDeviceInput = toVideoDeviceInput; } //提交會(huì)話(huà)配置 [self.captureSession commitConfiguration]; } //點(diǎn)按手勢(shì) - (void)tapScreen:(UITapGestureRecognizer *)tap { CGPoint point = [tap locationInView:self.viewContainer]; //將界面point對(duì)應(yīng)到攝像頭point CGPoint cameraPoint = [self.captureVideoPreviewLayer captureDevicePointOfInterestForPoint:point]; //設(shè)置聚光動(dòng)畫(huà) self.focusCursor.center = point; self.focusCursor.transform = CGAffineTransformMakeScale(1.5, 1.5); self.focusCursor.alpha = 1.0f; [UIView animateWithDuration:1 animations:^{ self.focusCursor.transform = CGAffineTransformIdentity; } completion:^(BOOL finished) { self.focusCursor.alpha = 0.0f; }]; //設(shè)置聚光點(diǎn)坐標(biāo) [self focusWithMode:AVCaptureFocusModeAutoFocus exposureMode:AVCaptureExposureModeAutoExpose atPoint:cameraPoint]; } /**設(shè)置聚焦點(diǎn)*/ -(void)focusWithMode:(AVCaptureFocusMode)focusMode exposureMode:(AVCaptureExposureMode)exposureMode atPoint:(CGPoint)point{ AVCaptureDevice *captureDevice= [self.videoCaptureDeviceInput device]; NSError *error = nil; //設(shè)置設(shè)備屬性必須先解鎖 然后加鎖 if ([captureDevice lockForConfiguration:&error]) { if ([captureDevice isFocusModeSupported:focusMode]) { [captureDevice setFocusMode:focusMode]; } if ([captureDevice isFocusPointOfInterestSupported]) { [captureDevice setFocusPointOfInterest:point]; } // //曝光 // if ([captureDevice isExposureModeSupported:exposureMode]) { // [captureDevice setExposureMode:exposureMode]; // } // if ([captureDevice isExposurePointOfInterestSupported]) { // [captureDevice setExposurePointOfInterest:point]; // } // //閃光燈模式 // if ([captureDevice isFlashModeSupported:AVCaptureFlashModeAuto]) { // [captureDevice setFlashMode:AVCaptureFlashModeAuto]; // } //加鎖 [captureDevice unlockForConfiguration]; }else{ NSLog(@"設(shè)置設(shè)備屬性過(guò)程發(fā)生錯(cuò)誤,錯(cuò)誤信息:%@",error.localizedDescription); } } //調(diào)整焦距 -(void)scaleBtnClick:(UIButton *)sender { _kCameraScale += 0.5; if(_kCameraScale > 3.0) { _kCameraScale = 1.0; } //改變焦距 AVCaptureDevice *videoDevice = self.videoCaptureDeviceInput.device; NSError *error = nil; if ([videoDevice lockForConfiguration:&error]) { [videoDevice setVideoZoomFactor:_kCameraScale]; [videoDevice unlockForConfiguration]; [sender setTitle:[NSString stringWithFormat:@"%lgX",_kCameraScale] forState:UIControlStateNormal]; [CATransaction begin]; [CATransaction setAnimationDuration:0.25]; [self.captureVideoPreviewLayer setAffineTransform:CGAffineTransformMakeScale(_kCameraScale, _kCameraScale)]; [CATransaction commit]; } else { NSLog(@"修改設(shè)備屬性失敗!") } } #pragma mark -------- AVCaptureFileOutputRecordingDelegate ---------- - (void)captureOutput:(AVCaptureFileOutput *)captureOutput didStartRecordingToOutputFileAtURL:(NSURL *)fileURL fromConnections:(NSArray *)connections { NSLog(@"開(kāi)始錄制"); } - (void)captureOutput:(AVCaptureFileOutput *)captureOutput didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL fromConnections:(NSArray *)connections error:(NSError *)error { NSLog(@"錄制結(jié)束"); ALAssetsLibrary *assetsLibrary = [[ALAssetsLibrary alloc] init]; [assetsLibrary writeVideoAtPathToSavedPhotosAlbum:outputFileURL completionBlock:^(NSURL *assetURL, NSError *error) { if (error) { NSLog(@"保存視頻到相簿過(guò)程中發(fā)生錯(cuò)誤,錯(cuò)誤信息:%@",error.localizedDescription); } }]; } //錄制計(jì)時(shí) - (void)timeAction { self.timeLabel.text = [NSString stringWithFormat:@"%.2ld:%.2ld",_num/60,_num%60]; _num ++; } /**取得指定位置的攝像頭*/ - (AVCaptureDevice *)cameraDeviceWithPosition:(AVCaptureDevicePosition )position{ NSArray *cameras = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]; for (AVCaptureDevice *camera in cameras) { if ([camera position] == position) { return camera; } } return nil; } @end
參考代碼:
#import "VideoTestViewController.h" #import <AVFoundation/AVFoundation.h> #import <AssetsLibrary/AssetsLibrary.h> typedef void(^PropertyChangeBlock)(AVCaptureDevice *captureDevice); @interface VideoTestViewController ()<AVCaptureFileOutputRecordingDelegate>//視頻文件輸出代理 @property (strong,nonatomic) AVCaptureSession *captureSession;//負(fù)責(zé)輸入和輸出設(shè)備之間的數(shù)據(jù)傳遞 @property (strong,nonatomic) AVCaptureDeviceInput *captureDeviceInput;//負(fù)責(zé)從AVCaptureDevice獲得輸入數(shù)據(jù) @property (strong,nonatomic) AVCaptureMovieFileOutput *captureMovieFileOutput;//視頻輸出流 @property (strong,nonatomic) AVCaptureVideoPreviewLayer *captureVideoPreviewLayer;//相機(jī)拍攝預(yù)覽圖層 @property (assign,nonatomic) BOOL enableRotation;//是否允許旋轉(zhuǎn)(注意在視頻錄制過(guò)程中禁止屏幕旋轉(zhuǎn)) @property (assign,nonatomic) CGRect *lastBounds;//旋轉(zhuǎn)的前大小 @property (assign,nonatomic) UIBackgroundTaskIdentifier backgroundTaskIdentifier;//后臺(tái)任務(wù)標(biāo)識(shí) @property (strong,nonatomic) UIView *viewContainer; @property (strong,nonatomic) UIButton *takeButton;//拍照按鈕 @property (strong,nonatomic) UIImageView *focusCursor; //聚焦光標(biāo) @end @implementation VideoTestViewController #pragma mark - 控制器視圖方法 - (void)viewDidLoad { [super viewDidLoad]; } -(void)viewWillAppear:(BOOL)animated{ [super viewWillAppear:animated]; //初始化會(huì)話(huà) _captureSession=[[AVCaptureSession alloc]init]; if ([_captureSession canSetSessionPreset:AVCaptureSessionPreset1280x720]) {//設(shè)置分辨率 _captureSession.sessionPreset=AVCaptureSessionPreset1280x720; } //獲得輸入設(shè)備 AVCaptureDevice *captureDevice=[self getCameraDeviceWithPosition:AVCaptureDevicePositionBack];//取得后置攝像頭 if (!captureDevice) { NSLog(@"取得后置攝像頭時(shí)出現(xiàn)問(wèn)題."); return; } //添加一個(gè)音頻輸入設(shè)備 AVCaptureDevice *audioCaptureDevice=[[AVCaptureDevice devicesWithMediaType:AVMediaTypeAudio] firstObject]; NSError *error=nil; //根據(jù)輸入設(shè)備初始化設(shè)備輸入對(duì)象,用于獲得輸入數(shù)據(jù) _captureDeviceInput=[[AVCaptureDeviceInput alloc]initWithDevice:captureDevice error:&error]; if (error) { NSLog(@"取得設(shè)備輸入對(duì)象時(shí)出錯(cuò),錯(cuò)誤原因:%@",error.localizedDescription); return; } AVCaptureDeviceInput *audioCaptureDeviceInput=[[AVCaptureDeviceInput alloc]initWithDevice:audioCaptureDevice error:&error]; if (error) { NSLog(@"取得設(shè)備輸入對(duì)象時(shí)出錯(cuò),錯(cuò)誤原因:%@",error.localizedDescription); return; } //初始化設(shè)備輸出對(duì)象,用于獲得輸出數(shù)據(jù) _captureMovieFileOutput=[[AVCaptureMovieFileOutput alloc]init]; //將設(shè)備輸入添加到會(huì)話(huà)中 if ([_captureSession canAddInput:_captureDeviceInput]) { [_captureSession addInput:_captureDeviceInput]; [_captureSession addInput:audioCaptureDeviceInput]; AVCaptureConnection *captureConnection=[_captureMovieFileOutput connectionWithMediaType:AVMediaTypeVideo]; if ([captureConnection isVideoStabilizationSupported ]) { captureConnection.preferredVideoStabilizationMode=AVCaptureVideoStabilizationModeAuto; } } //將設(shè)備輸出添加到會(huì)話(huà)中 if ([_captureSession canAddOutput:_captureMovieFileOutput]) { [_captureSession addOutput:_captureMovieFileOutput]; } //創(chuàng)建視頻預(yù)覽層,用于實(shí)時(shí)展示攝像頭狀態(tài) _captureVideoPreviewLayer=[[AVCaptureVideoPreviewLayer alloc]initWithSession:self.captureSession]; CALayer *layer=self.viewContainer.layer; layer.masksToBounds=YES; _captureVideoPreviewLayer.frame=layer.bounds; _captureVideoPreviewLayer.videoGravity=AVLayerVideoGravityResizeAspectFill;//填充模式 //將視頻預(yù)覽層添加到界面中 //[layer addSublayer:_captureVideoPreviewLayer]; [layer insertSublayer:_captureVideoPreviewLayer below:self.focusCursor.layer]; _enableRotation=YES; [self addNotificationToCaptureDevice:captureDevice]; [self addGenstureRecognizer]; } -(void)viewDidAppear:(BOOL)animated{ [super viewDidAppear:animated]; [self.captureSession startRunning]; } -(void)viewDidDisappear:(BOOL)animated{ [super viewDidDisappear:animated]; [self.captureSession stopRunning]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; } -(BOOL)shouldAutorotate{ return self.enableRotation; } ////屏幕旋轉(zhuǎn)時(shí)調(diào)整視頻預(yù)覽圖層的方向 //-(void)willTransitionToTraitCollection:(UITraitCollection *)newCollection withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator{ // [super willTransitionToTraitCollection:newCollection withTransitionCoordinator:coordinator]; //// NSLog(@"%i,%i",newCollection.verticalSizeClass,newCollection.horizontalSizeClass); // UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation]; // NSLog(@"%i",orientation); // AVCaptureConnection *captureConnection=[self.captureVideoPreviewLayer connection]; // captureConnection.videoOrientation=orientation; // //} //屏幕旋轉(zhuǎn)時(shí)調(diào)整視頻預(yù)覽圖層的方向 -(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{ AVCaptureConnection *captureConnection=[self.captureVideoPreviewLayer connection]; captureConnection.videoOrientation=(AVCaptureVideoOrientation)toInterfaceOrientation; } //旋轉(zhuǎn)后重新設(shè)置大小 -(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation{ _captureVideoPreviewLayer.frame=self.viewContainer.bounds; } -(void)dealloc{ [self removeNotification]; } #pragma mark - UI方法 #pragma mark 視頻錄制 - (void)takeButtonClick:(UIButton *)sender { //根據(jù)設(shè)備輸出獲得連接 AVCaptureConnection *captureConnection=[self.captureMovieFileOutput connectionWithMediaType:AVMediaTypeVideo]; //根據(jù)連接取得設(shè)備輸出的數(shù)據(jù) if (![self.captureMovieFileOutput isRecording]) { self.enableRotation=NO; //如果支持多任務(wù)則則開(kāi)始多任務(wù) if ([[UIDevice currentDevice] isMultitaskingSupported]) { self.backgroundTaskIdentifier=[[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:nil]; } //預(yù)覽圖層和視頻方向保持一致 captureConnection.videoOrientation=[self.captureVideoPreviewLayer connection].videoOrientation; NSString *outputFielPath=[NSTemporaryDirectory() stringByAppendingString:@"myMovie.mov"]; NSLog(@"save path is :%@",outputFielPath); NSURL *fileUrl=[NSURL fileURLWithPath:outputFielPath]; [self.captureMovieFileOutput startRecordingToOutputFileURL:fileUrl recordingDelegate:self]; } else{ [self.captureMovieFileOutput stopRecording];//停止錄制 } } #pragma mark 切換前后攝像頭 - (void)toggleButtonClick:(UIButton *)sender { AVCaptureDevice *currentDevice=[self.captureDeviceInput device]; AVCaptureDevicePosition currentPosition=[currentDevice position]; [self removeNotificationFromCaptureDevice:currentDevice]; AVCaptureDevice *toChangeDevice; AVCaptureDevicePosition toChangePosition=AVCaptureDevicePositionFront; if (currentPosition==AVCaptureDevicePositionUnspecified||currentPosition==AVCaptureDevicePositionFront) { toChangePosition=AVCaptureDevicePositionBack; } toChangeDevice=[self getCameraDeviceWithPosition:toChangePosition]; [self addNotificationToCaptureDevice:toChangeDevice]; //獲得要調(diào)整的設(shè)備輸入對(duì)象 AVCaptureDeviceInput *toChangeDeviceInput=[[AVCaptureDeviceInput alloc]initWithDevice:toChangeDevice error:nil]; //改變會(huì)話(huà)的配置前一定要先開(kāi)啟配置,配置完成后提交配置改變 [self.captureSession beginConfiguration]; //移除原有輸入對(duì)象 [self.captureSession removeInput:self.captureDeviceInput]; //添加新的輸入對(duì)象 if ([self.captureSession canAddInput:toChangeDeviceInput]) { [self.captureSession addInput:toChangeDeviceInput]; self.captureDeviceInput=toChangeDeviceInput; } //提交會(huì)話(huà)配置 [self.captureSession commitConfiguration]; } #pragma mark - 視頻輸出代理 -(void)captureOutput:(AVCaptureFileOutput *)captureOutput didStartRecordingToOutputFileAtURL:(NSURL *)fileURL fromConnections:(NSArray *)connections{ NSLog(@"開(kāi)始錄制..."); } -(void)captureOutput:(AVCaptureFileOutput *)captureOutput didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL fromConnections:(NSArray *)connections error:(NSError *)error{ NSLog(@"視頻錄制完成."); //視頻錄入完成之后在后臺(tái)將視頻存儲(chǔ)到相簿 self.enableRotation=YES; UIBackgroundTaskIdentifier lastBackgroundTaskIdentifier=self.backgroundTaskIdentifier; self.backgroundTaskIdentifier=UIBackgroundTaskInvalid; ALAssetsLibrary *assetsLibrary=[[ALAssetsLibrary alloc]init]; [assetsLibrary writeVideoAtPathToSavedPhotosAlbum:outputFileURL completionBlock:^(NSURL *assetURL, NSError *error) { if (error) { NSLog(@"保存視頻到相簿過(guò)程中發(fā)生錯(cuò)誤,錯(cuò)誤信息:%@",error.localizedDescription); } if (lastBackgroundTaskIdentifier!=UIBackgroundTaskInvalid) { [[UIApplication sharedApplication] endBackgroundTask:lastBackgroundTaskIdentifier]; } NSLog(@"成功保存視頻到相簿."); }]; } #pragma mark - 通知 /** * 給輸入設(shè)備添加通知 */ -(void)addNotificationToCaptureDevice:(AVCaptureDevice *)captureDevice{ //注意添加區(qū)域改變捕獲通知必須首先設(shè)置設(shè)備允許捕獲 [self changeDeviceProperty:^(AVCaptureDevice *captureDevice) { captureDevice.subjectAreaChangeMonitoringEnabled=YES; }]; NSNotificationCenter *notificationCenter= [NSNotificationCenter defaultCenter]; //捕獲區(qū)域發(fā)生改變 [notificationCenter addObserver:self selector:@selector(areaChange:) name:AVCaptureDeviceSubjectAreaDidChangeNotification object:captureDevice]; } -(void)removeNotificationFromCaptureDevice:(AVCaptureDevice *)captureDevice{ NSNotificationCenter *notificationCenter= [NSNotificationCenter defaultCenter]; [notificationCenter removeObserver:self name:AVCaptureDeviceSubjectAreaDidChangeNotification object:captureDevice]; } /** * 移除所有通知 */ -(void)removeNotification{ NSNotificationCenter *notificationCenter= [NSNotificationCenter defaultCenter]; [notificationCenter removeObserver:self]; } -(void)addNotificationToCaptureSession:(AVCaptureSession *)captureSession{ NSNotificationCenter *notificationCenter= [NSNotificationCenter defaultCenter]; //會(huì)話(huà)出錯(cuò) [notificationCenter addObserver:self selector:@selector(sessionRuntimeError:) name:AVCaptureSessionRuntimeErrorNotification object:captureSession]; } /** * 設(shè)備連接成功 * * @param notification 通知對(duì)象 */ -(void)deviceConnected:(NSNotification *)notification{ NSLog(@"設(shè)備已連接..."); } /** * 設(shè)備連接斷開(kāi) * * @param notification 通知對(duì)象 */ -(void)deviceDisconnected:(NSNotification *)notification{ NSLog(@"設(shè)備已斷開(kāi)."); } /** * 捕獲區(qū)域改變 * * @param notification 通知對(duì)象 */ -(void)areaChange:(NSNotification *)notification{ NSLog(@"捕獲區(qū)域改變..."); } /** * 會(huì)話(huà)出錯(cuò) * * @param notification 通知對(duì)象 */ -(void)sessionRuntimeError:(NSNotification *)notification{ NSLog(@"會(huì)話(huà)發(fā)生錯(cuò)誤."); } #pragma mark - 私有方法 /** * 取得指定位置的攝像頭 * * @param position 攝像頭位置 * * @return 攝像頭設(shè)備 */ -(AVCaptureDevice *)getCameraDeviceWithPosition:(AVCaptureDevicePosition )position{ NSArray *cameras= [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]; for (AVCaptureDevice *camera in cameras) { if ([camera position]==position) { return camera; } } return nil; } /** * 改變?cè)O(shè)備屬性的統(tǒng)一操作方法 * * @param propertyChange 屬性改變操作 */ -(void)changeDeviceProperty:(PropertyChangeBlock)propertyChange{ AVCaptureDevice *captureDevice= [self.captureDeviceInput device]; NSError *error; //注意改變?cè)O(shè)備屬性前一定要首先調(diào)用lockForConfiguration:調(diào)用完之后使用unlockForConfiguration方法解鎖 if ([captureDevice lockForConfiguration:&error]) { propertyChange(captureDevice); [captureDevice unlockForConfiguration]; }else{ NSLog(@"設(shè)置設(shè)備屬性過(guò)程發(fā)生錯(cuò)誤,錯(cuò)誤信息:%@",error.localizedDescription); } } /** * 設(shè)置閃光燈模式 * * @param flashMode 閃光燈模式 */ -(void)setFlashMode:(AVCaptureFlashMode )flashMode{ [self changeDeviceProperty:^(AVCaptureDevice *captureDevice) { if ([captureDevice isFlashModeSupported:flashMode]) { [captureDevice setFlashMode:flashMode]; } }]; } /** * 設(shè)置聚焦模式 * * @param focusMode 聚焦模式 */ -(void)setFocusMode:(AVCaptureFocusMode )focusMode{ [self changeDeviceProperty:^(AVCaptureDevice *captureDevice) { if ([captureDevice isFocusModeSupported:focusMode]) { [captureDevice setFocusMode:focusMode]; } }]; } /** * 設(shè)置曝光模式 * * @param exposureMode 曝光模式 */ -(void)setExposureMode:(AVCaptureExposureMode)exposureMode{ [self changeDeviceProperty:^(AVCaptureDevice *captureDevice) { if ([captureDevice isExposureModeSupported:exposureMode]) { [captureDevice setExposureMode:exposureMode]; } }]; } /** * 設(shè)置聚焦點(diǎn) * * @param point 聚焦點(diǎn) */ -(void)focusWithMode:(AVCaptureFocusMode)focusMode exposureMode:(AVCaptureExposureMode)exposureMode atPoint:(CGPoint)point{ [self changeDeviceProperty:^(AVCaptureDevice *captureDevice) { if ([captureDevice isFocusModeSupported:focusMode]) { [captureDevice setFocusMode:AVCaptureFocusModeAutoFocus]; } if ([captureDevice isFocusPointOfInterestSupported]) { [captureDevice setFocusPointOfInterest:point]; } if ([captureDevice isExposureModeSupported:exposureMode]) { [captureDevice setExposureMode:AVCaptureExposureModeAutoExpose]; } if ([captureDevice isExposurePointOfInterestSupported]) { [captureDevice setExposurePointOfInterest:point]; } }]; } /** * 添加點(diǎn)按手勢(shì),點(diǎn)按時(shí)聚焦 */ -(void)addGenstureRecognizer{ UITapGestureRecognizer *tapGesture=[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapScreen:)]; [self.viewContainer addGestureRecognizer:tapGesture]; } -(void)tapScreen:(UITapGestureRecognizer *)tapGesture{ CGPoint point= [tapGesture locationInView:self.viewContainer]; //將UI坐標(biāo)轉(zhuǎn)化為攝像頭坐標(biāo) CGPoint cameraPoint= [self.captureVideoPreviewLayer captureDevicePointOfInterestForPoint:point]; [self setFocusCursorWithPoint:point]; [self focusWithMode:AVCaptureFocusModeAutoFocus exposureMode:AVCaptureExposureModeAutoExpose atPoint:cameraPoint]; } /** * 設(shè)置聚焦光標(biāo)位置 * * @param point 光標(biāo)位置 */ -(void)setFocusCursorWithPoint:(CGPoint)point{ self.focusCursor.center=point; self.focusCursor.transform=CGAffineTransformMakeScale(1.5, 1.5); self.focusCursor.alpha=1.0; [UIView animateWithDuration:1.0 animations:^{ self.focusCursor.transform=CGAffineTransformIdentity; } completion:^(BOOL finished) { self.focusCursor.alpha=0; }]; } @end
以上就是怎么在iOS中使用AVCaptureSession實(shí)現(xiàn)視頻錄制功能,小編相信有部分知識(shí)點(diǎn)可能是我們?nèi)粘9ぷ鲿?huì)見(jiàn)到或用到的。希望你能通過(guò)這篇文章學(xué)到更多知識(shí)。更多詳情敬請(qǐng)關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。