欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

iOS AVCaptureSession實現(xiàn)視頻錄制功能

 更新時間:2018年05月07日 16:00:16   作者:NB_Token  
這篇文章主要為大家詳細(xì)介紹了iOS AVCaptureSession實現(xiàn)視頻錄制功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下

本文實例為大家分享了AVCaptureSession實現(xiàn)視頻錄制功能的具體代碼,供大家參考,具體內(nèi)容如下

#import "RecordingVideoViewController.h" 
#import <AVFoundation/AVFoundation.h> 
#import <AssetsLibrary/AssetsLibrary.h> 
 
@interface RecordingVideoViewController ()<AVCaptureFileOutputRecordingDelegate> 
 
//會話 負(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; 
//相機拍攝預(yù)覽圖層 
@property (strong,nonatomic) AVCaptureVideoPreviewLayer  *captureVideoPreviewLayer; 
 
//自定義UI控件容器 
@property (strong,nonatomic) UIView  *viewContainer; 
//聚焦圖標(biāo) 
@property (strong,nonatomic) UIImageView  *focusCursor; 
//錄制時長 
@property (strong,nonatomic) UILabel  *timeLabel; 
//切換前后攝像頭 
@property (strong,nonatomic) UIButton  *switchCameraBtn; 
//改變焦距 
@property (strong,nonatomic) UIButton  *scaleBtn; 
//計時器 
@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; 
  //初始化會話對象 
  _captureSession = [[AVCaptureSession alloc] init]; 
  if ([_captureSession canSetSessionPreset:AVCaptureSessionPreset1280x720]) { 
    _captureSession.sessionPreset = AVCaptureSessionPreset1280x720; 
  } 
   
   
  NSError *error = nil; 
 
  //獲取視頻輸入對象 
  AVCaptureDevice *videoCaptureDevice = [self cameraDeviceWithPosition:(AVCaptureDevicePositionBack)]; 
  if (!videoCaptureDevice) { 
    NSLog(@"獲取后置攝像頭失敗!"); 
    return; 
  } 
  _videoCaptureDeviceInput = [[AVCaptureDeviceInput alloc] initWithDevice:videoCaptureDevice error:&error]; 
  if (error) { 
    NSLog(@"取得視頻設(shè)備輸入對象時出錯"); 
    return; 
  } 
   
   
  //獲取音頻輸入對象 
  AVCaptureDevice *audioCatureDevice = [[AVCaptureDevice devicesWithMediaType:AVMediaTypeAudio] firstObject]; 
  _audioCaptureDeviceInput = [[AVCaptureDeviceInput alloc] initWithDevice:audioCatureDevice error:&error]; 
  if (error) { 
    NSLog(@"取得音頻設(shè)備輸入對象時出錯"); 
    return; 
  } 
   
  //初始化設(shè)備輸出對象 
  _captureMovieFileOutput = [[AVCaptureMovieFileOutput alloc] init]; 
   
  //將設(shè)備輸入添加到會話中 
  if ([_captureSession canAddInput:_videoCaptureDeviceInput]) { 
    [_captureSession addInput:_videoCaptureDeviceInput]; 
    [_captureSession addInput:_audioCaptureDeviceInput]; 
     
    //防抖功能 
    AVCaptureConnection *captureConnection = [_captureMovieFileOutput connectionWithMediaType:AVMediaTypeAudio]; 
    if ([captureConnection isVideoStabilizationSupported]) { 
      captureConnection.preferredVideoStabilizationMode = AVCaptureVideoStabilizationModeAuto; 
    } 
  } 
   
  //將設(shè)備輸出添加到會話中 
  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]; 
   
  //添加點按聚焦手勢 
  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]; 
} 
 
//開始 + 暫停錄制 
- (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; 
  } 
   
  //改變會話配置 
  [self.captureSession beginConfiguration]; 
   
  [self.captureSession removeInput:self.videoCaptureDeviceInput]; 
  if ([self.captureSession canAddInput:toVideoDeviceInput]) { 
    [self.captureSession addInput:toVideoDeviceInput]; 
     
    self.videoCaptureDeviceInput = toVideoDeviceInput; 
  } 
  //提交會話配置 
  [self.captureSession commitConfiguration]; 
} 
 
 
//點按手勢 
- (void)tapScreen:(UITapGestureRecognizer *)tap { 
  CGPoint point = [tap locationInView:self.viewContainer]; 
   
  //將界面point對應(yīng)到攝像頭point 
  CGPoint cameraPoint = [self.captureVideoPreviewLayer captureDevicePointOfInterestForPoint:point]; 
 
  //設(shè)置聚光動畫 
  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è)置聚光點坐標(biāo) 
  [self focusWithMode:AVCaptureFocusModeAutoFocus exposureMode:AVCaptureExposureModeAutoExpose atPoint:cameraPoint]; 
 
} 
 
 
/**設(shè)置聚焦點*/ 
-(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è)備屬性過程發(fā)生錯誤,錯誤信息:%@",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(@"開始錄制"); 
} 
 
- (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(@"保存視頻到相簿過程中發(fā)生錯誤,錯誤信息:%@",error.localizedDescription); 
    } 
  }]; 
} 
 
//錄制計時 
- (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;//相機拍攝預(yù)覽圖層 
 
@property (assign,nonatomic) BOOL enableRotation;//是否允許旋轉(zhuǎn)(注意在視頻錄制過程中禁止屏幕旋轉(zhuǎn)) 
@property (assign,nonatomic) CGRect *lastBounds;//旋轉(zhuǎn)的前大小 
@property (assign,nonatomic) UIBackgroundTaskIdentifier backgroundTaskIdentifier;//后臺任務(wù)標(biāo)識 
@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]; 
   
  //初始化會話 
  _captureSession=[[AVCaptureSession alloc]init]; 
  if ([_captureSession canSetSessionPreset:AVCaptureSessionPreset1280x720]) {//設(shè)置分辨率 
    _captureSession.sessionPreset=AVCaptureSessionPreset1280x720; 
  } 
  //獲得輸入設(shè)備 
  AVCaptureDevice *captureDevice=[self getCameraDeviceWithPosition:AVCaptureDevicePositionBack];//取得后置攝像頭 
  if (!captureDevice) { 
    NSLog(@"取得后置攝像頭時出現(xiàn)問題."); 
    return; 
  } 
  //添加一個音頻輸入設(shè)備 
  AVCaptureDevice *audioCaptureDevice=[[AVCaptureDevice devicesWithMediaType:AVMediaTypeAudio] firstObject]; 
   
   
  NSError *error=nil; 
  //根據(jù)輸入設(shè)備初始化設(shè)備輸入對象,用于獲得輸入數(shù)據(jù) 
  _captureDeviceInput=[[AVCaptureDeviceInput alloc]initWithDevice:captureDevice error:&error]; 
  if (error) { 
    NSLog(@"取得設(shè)備輸入對象時出錯,錯誤原因:%@",error.localizedDescription); 
    return; 
  } 
  AVCaptureDeviceInput *audioCaptureDeviceInput=[[AVCaptureDeviceInput alloc]initWithDevice:audioCaptureDevice error:&error]; 
  if (error) { 
    NSLog(@"取得設(shè)備輸入對象時出錯,錯誤原因:%@",error.localizedDescription); 
    return; 
  } 
  //初始化設(shè)備輸出對象,用于獲得輸出數(shù)據(jù) 
  _captureMovieFileOutput=[[AVCaptureMovieFileOutput alloc]init]; 
   
  //將設(shè)備輸入添加到會話中 
  if ([_captureSession canAddInput:_captureDeviceInput]) { 
    [_captureSession addInput:_captureDeviceInput]; 
    [_captureSession addInput:audioCaptureDeviceInput]; 
    AVCaptureConnection *captureConnection=[_captureMovieFileOutput connectionWithMediaType:AVMediaTypeVideo]; 
    if ([captureConnection isVideoStabilizationSupported ]) { 
      captureConnection.preferredVideoStabilizationMode=AVCaptureVideoStabilizationModeAuto; 
    } 
  } 
   
  //將設(shè)備輸出添加到會話中 
  if ([_captureSession canAddOutput:_captureMovieFileOutput]) { 
    [_captureSession addOutput:_captureMovieFileOutput]; 
  } 
   
  //創(chuàng)建視頻預(yù)覽層,用于實時展示攝像頭狀態(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)時調(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)時調(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ù)則則開始多任務(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è)備輸入對象 
  AVCaptureDeviceInput *toChangeDeviceInput=[[AVCaptureDeviceInput alloc]initWithDevice:toChangeDevice error:nil]; 
   
  //改變會話的配置前一定要先開啟配置,配置完成后提交配置改變 
  [self.captureSession beginConfiguration]; 
  //移除原有輸入對象 
  [self.captureSession removeInput:self.captureDeviceInput]; 
  //添加新的輸入對象 
  if ([self.captureSession canAddInput:toChangeDeviceInput]) { 
    [self.captureSession addInput:toChangeDeviceInput]; 
    self.captureDeviceInput=toChangeDeviceInput; 
  } 
  //提交會話配置 
  [self.captureSession commitConfiguration]; 
   
} 
 
#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(@"視頻錄制完成."); 
  //視頻錄入完成之后在后臺將視頻存儲到相簿 
  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(@"保存視頻到相簿過程中發(fā)生錯誤,錯誤信息:%@",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]; 
  //會話出錯 
  [notificationCenter addObserver:self selector:@selector(sessionRuntimeError:) name:AVCaptureSessionRuntimeErrorNotification object:captureSession]; 
} 
 
/** 
 * 設(shè)備連接成功 
 * 
 * @param notification 通知對象 
 */ 
-(void)deviceConnected:(NSNotification *)notification{ 
  NSLog(@"設(shè)備已連接..."); 
} 
/** 
 * 設(shè)備連接斷開 
 * 
 * @param notification 通知對象 
 */ 
-(void)deviceDisconnected:(NSNotification *)notification{ 
  NSLog(@"設(shè)備已斷開."); 
} 
/** 
 * 捕獲區(qū)域改變 
 * 
 * @param notification 通知對象 
 */ 
-(void)areaChange:(NSNotification *)notification{ 
  NSLog(@"捕獲區(qū)域改變..."); 
} 
 
/** 
 * 會話出錯 
 * 
 * @param notification 通知對象 
 */ 
-(void)sessionRuntimeError:(NSNotification *)notification{ 
  NSLog(@"會話發(fā)生錯誤."); 
} 
 
#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; 
} 
 
/** 
 * 改變設(shè)備屬性的統(tǒng)一操作方法 
 * 
 * @param propertyChange 屬性改變操作 
 */ 
-(void)changeDeviceProperty:(PropertyChangeBlock)propertyChange{ 
  AVCaptureDevice *captureDevice= [self.captureDeviceInput device]; 
  NSError *error; 
  //注意改變設(shè)備屬性前一定要首先調(diào)用lockForConfiguration:調(diào)用完之后使用unlockForConfiguration方法解鎖 
  if ([captureDevice lockForConfiguration:&error]) { 
    propertyChange(captureDevice); 
    [captureDevice unlockForConfiguration]; 
  }else{ 
    NSLog(@"設(shè)置設(shè)備屬性過程發(fā)生錯誤,錯誤信息:%@",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è)置聚焦點 
 * 
 * @param point 聚焦點 
 */ 
-(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]; 
    } 
  }]; 
} 
 
/** 
 * 添加點按手勢,點按時聚焦 
 */ 
-(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 

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • iOS開發(fā)中使用文字圖標(biāo)iconfont的應(yīng)用示例

    iOS開發(fā)中使用文字圖標(biāo)iconfont的應(yīng)用示例

    這篇文章主要介紹了iOS開發(fā)中使用文字圖標(biāo)iconfont的應(yīng)用示例,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • 實例解析iOS開發(fā)中系統(tǒng)音效以及自定義音效的應(yīng)用

    實例解析iOS開發(fā)中系統(tǒng)音效以及自定義音效的應(yīng)用

    這篇文章主要介紹了iOS開發(fā)中系統(tǒng)音效以及自定義音效的應(yīng)用,代碼基于傳統(tǒng)的Objective-C,需要的朋友可以參考下
    2015-10-10
  • 詳解iOS App中UiTabBarController組件的基本用法

    詳解iOS App中UiTabBarController組件的基本用法

    UiTabBarController組件即是用來創(chuàng)建App中的Tab視圖切換選項欄,下面將詳解iOS App中UiTabBarController組件的基本用法,包括左右滑動切換標(biāo)簽頁等基本功能的實現(xiàn),需要的朋友可以參考下
    2016-05-05
  • 一步一步實現(xiàn)iOS主題皮膚切換效果

    一步一步實現(xiàn)iOS主題皮膚切換效果

    這篇文章主要為大家詳細(xì)介紹了一步一步實現(xiàn)iOS主題皮膚切換效果的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-09-09
  • iOS中的緩存計算和清除完整實例代碼

    iOS中的緩存計算和清除完整實例代碼

    iOS設(shè)備使用時間長了,一些應(yīng)用程序的緩存垃圾文件就會越存越多,這些文件堆積多了就會拖慢系統(tǒng)速度。因此,小編整理了iOS中的緩存計算和清除實例
    2017-04-04
  • IOS上iframe的滾動條失效的解決辦法

    IOS上iframe的滾動條失效的解決辦法

    這篇文章主要為大家詳細(xì)介紹了IOS上iframe的滾動條失效的解決辦法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-09-09
  • iOS實現(xiàn)去除html標(biāo)簽的方法匯總

    iOS實現(xiàn)去除html標(biāo)簽的方法匯總

    相信大家在做網(wǎng)站的時候,經(jīng)常會遇到去除html標(biāo)簽的問題,下面這篇文章主要給大家總結(jié)介紹了關(guān)于iOS如何實現(xiàn)去除html標(biāo)簽的一些方法,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-10-10
  • 詳解iOS使用Keychain中的kSecClassGenericPassword存儲數(shù)據(jù)

    詳解iOS使用Keychain中的kSecClassGenericPassword存儲數(shù)據(jù)

    iOS設(shè)備中的Keychain是一個安全的存儲容器,本篇文章主要介紹了iOS使用Keychain中的kSecClassGenericPassword存儲數(shù)據(jù),有興趣的可以了解一下。
    2016-11-11
  • iOS中常見的視圖和圖片處理示例詳解

    iOS中常見的視圖和圖片處理示例詳解

    在日常ios開發(fā)中經(jīng)常會遇到視圖和圖片的處理,下面這篇文章主要給大家總結(jié)介紹了關(guān)于iOS中常見的視圖和圖片處理的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)和工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下。
    2017-10-10
  • IOS開發(fā)中如何設(shè)計短信驗證碼防刷機制

    IOS開發(fā)中如何設(shè)計短信驗證碼防刷機制

    給大家詳細(xì)分享一下在IOS的項目開發(fā)中如何設(shè)計短信驗證碼防刷機制,已經(jīng)步驟詳解,喜歡的朋友參考下吧。
    2018-02-02

最新評論