iOS AVCaptureSession实现视频录制功能
程序员文章站
2023-12-18 14:33:58
本文实例为大家分享了avcapturesession实现视频录制功能的具体代码,供大家参考,具体内容如下
#import "recordingvideoviewc...
本文实例为大家分享了avcapturesession实现视频录制功能的具体代码,供大家参考,具体内容如下
#import "recordingvideoviewcontroller.h" #import <avfoundation/avfoundation.h> #import <assetslibrary/assetslibrary.h> @interface recordingvideoviewcontroller ()<avcapturefileoutputrecordingdelegate> //会话 负责输入和输出设备之间的数据传递 @property (strong,nonatomic) avcapturesession *capturesession; //设备输入 负责从avcapturedevice获得输入数据 @property (strong,nonatomic) avcapturedeviceinput *videocapturedeviceinput; @property (strong,nonatomic) avcapturedeviceinput *audiocapturedeviceinput; //视频输出流 @property (strong,nonatomic) avcapturemoviefileoutput *capturemoviefileoutput; //相机拍摄预览图层 @property (strong,nonatomic) avcapturevideopreviewlayer *capturevideopreviewlayer; //自定义ui控件容器 @property (strong,nonatomic) uiview *viewcontainer; //聚焦图标 @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(@"取得视频设备输入对象时出错"); return; } //获取音频输入对象 avcapturedevice *audiocaturedevice = [[avcapturedevice deviceswithmediatype:avmediatypeaudio] firstobject]; _audiocapturedeviceinput = [[avcapturedeviceinput alloc] initwithdevice:audiocaturedevice error:&error]; if (error) { nslog(@"取得音频设备输入对象时出错"); return; } //初始化设备输出对象 _capturemoviefileoutput = [[avcapturemoviefileoutput alloc] init]; //将设备输入添加到会话中 if ([_capturesession canaddinput:_videocapturedeviceinput]) { [_capturesession addinput:_videocapturedeviceinput]; [_capturesession addinput:_audiocapturedeviceinput]; //防抖功能 avcaptureconnection *captureconnection = [_capturemoviefileoutput connectionwithmediatype:avmediatypeaudio]; if ([captureconnection isvideostabilizationsupported]) { captureconnection.preferredvideostabilizationmode = avcapturevideostabilizationmodeauto; } } //将设备输出添加到会话中 if ([_capturesession canaddoutput:_capturemoviefileoutput]) { [_capturesession addoutput:_capturemoviefileoutput]; } //创建视频预览图层 _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(@"获取要切换的设备失败"); return; } nserror *error = nil; avcapturedeviceinput *tovideodeviceinput = [[avcapturedeviceinput alloc] initwithdevice:tocapturdevice error:&error]; if (error) { nslog(@"获取要切换的设备输入失败"); 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对应到摄像头point cgpoint camerapoint = [self.capturevideopreviewlayer capturedevicepointofinterestforpoint:point]; //设置聚光动画 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; }]; //设置聚光点坐标 [self focuswithmode:avcapturefocusmodeautofocus exposuremode:avcaptureexposuremodeautoexpose atpoint:camerapoint]; } /**设置聚焦点*/ -(void)focuswithmode:(avcapturefocusmode)focusmode exposuremode:(avcaptureexposuremode)exposuremode atpoint:(cgpoint)point{ avcapturedevice *capturedevice= [self.videocapturedeviceinput device]; nserror *error = nil; //设置设备属性必须先解锁 然后加锁 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(@"设置设备属性过程发生错误,错误信息:%@",error.localizeddescription); } } //调整焦距 -(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(@"修改设备属性失败!") } } #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(@"录制结束"); alassetslibrary *assetslibrary = [[alassetslibrary alloc] init]; [assetslibrary writevideoatpathtosavedphotosalbum:outputfileurl completionblock:^(nsurl *asseturl, nserror *error) { if (error) { nslog(@"保存视频到相簿过程中发生错误,错误信息:%@",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;//负责输入和输出设备之间的数据传递 @property (strong,nonatomic) avcapturedeviceinput *capturedeviceinput;//负责从avcapturedevice获得输入数据 @property (strong,nonatomic) avcapturemoviefileoutput *capturemoviefileoutput;//视频输出流 @property (strong,nonatomic) avcapturevideopreviewlayer *capturevideopreviewlayer;//相机拍摄预览图层 @property (assign,nonatomic) bool enablerotation;//是否允许旋转(注意在视频录制过程中禁止屏幕旋转) @property (assign,nonatomic) cgrect *lastbounds;//旋转的前大小 @property (assign,nonatomic) uibackgroundtaskidentifier backgroundtaskidentifier;//后台任务标识 @property (strong,nonatomic) uiview *viewcontainer; @property (strong,nonatomic) uibutton *takebutton;//拍照按钮 @property (strong,nonatomic) uiimageview *focuscursor; //聚焦光标 @end @implementation videotestviewcontroller #pragma mark - 控制器视图方法 - (void)viewdidload { [super viewdidload]; } -(void)viewwillappear:(bool)animated{ [super viewwillappear:animated]; //初始化会话 _capturesession=[[avcapturesession alloc]init]; if ([_capturesession cansetsessionpreset:avcapturesessionpreset1280x720]) {//设置分辨率 _capturesession.sessionpreset=avcapturesessionpreset1280x720; } //获得输入设备 avcapturedevice *capturedevice=[self getcameradevicewithposition:avcapturedevicepositionback];//取得后置摄像头 if (!capturedevice) { nslog(@"取得后置摄像头时出现问题."); return; } //添加一个音频输入设备 avcapturedevice *audiocapturedevice=[[avcapturedevice deviceswithmediatype:avmediatypeaudio] firstobject]; nserror *error=nil; //根据输入设备初始化设备输入对象,用于获得输入数据 _capturedeviceinput=[[avcapturedeviceinput alloc]initwithdevice:capturedevice error:&error]; if (error) { nslog(@"取得设备输入对象时出错,错误原因:%@",error.localizeddescription); return; } avcapturedeviceinput *audiocapturedeviceinput=[[avcapturedeviceinput alloc]initwithdevice:audiocapturedevice error:&error]; if (error) { nslog(@"取得设备输入对象时出错,错误原因:%@",error.localizeddescription); return; } //初始化设备输出对象,用于获得输出数据 _capturemoviefileoutput=[[avcapturemoviefileoutput alloc]init]; //将设备输入添加到会话中 if ([_capturesession canaddinput:_capturedeviceinput]) { [_capturesession addinput:_capturedeviceinput]; [_capturesession addinput:audiocapturedeviceinput]; avcaptureconnection *captureconnection=[_capturemoviefileoutput connectionwithmediatype:avmediatypevideo]; if ([captureconnection isvideostabilizationsupported ]) { captureconnection.preferredvideostabilizationmode=avcapturevideostabilizationmodeauto; } } //将设备输出添加到会话中 if ([_capturesession canaddoutput:_capturemoviefileoutput]) { [_capturesession addoutput:_capturemoviefileoutput]; } //创建视频预览层,用于实时展示摄像头状态 _capturevideopreviewlayer=[[avcapturevideopreviewlayer alloc]initwithsession:self.capturesession]; calayer *layer=self.viewcontainer.layer; layer.maskstobounds=yes; _capturevideopreviewlayer.frame=layer.bounds; _capturevideopreviewlayer.videogravity=avlayervideogravityresizeaspectfill;//填充模式 //将视频预览层添加到界面中 //[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; } ////屏幕旋转时调整视频预览图层的方向 //-(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; // //} //屏幕旋转时调整视频预览图层的方向 -(void)willrotatetointerfaceorientation:(uiinterfaceorientation)tointerfaceorientation duration:(nstimeinterval)duration{ avcaptureconnection *captureconnection=[self.capturevideopreviewlayer connection]; captureconnection.videoorientation=(avcapturevideoorientation)tointerfaceorientation; } //旋转后重新设置大小 -(void)didrotatefrominterfaceorientation:(uiinterfaceorientation)frominterfaceorientation{ _capturevideopreviewlayer.frame=self.viewcontainer.bounds; } -(void)dealloc{ [self removenotification]; } #pragma mark - ui方法 #pragma mark 视频录制 - (void)takebuttonclick:(uibutton *)sender { //根据设备输出获得连接 avcaptureconnection *captureconnection=[self.capturemoviefileoutput connectionwithmediatype:avmediatypevideo]; //根据连接取得设备输出的数据 if (![self.capturemoviefileoutput isrecording]) { self.enablerotation=no; //如果支持多任务则则开始多任务 if ([[uidevice currentdevice] ismultitaskingsupported]) { self.backgroundtaskidentifier=[[uiapplication sharedapplication] beginbackgroundtaskwithexpirationhandler:nil]; } //预览图层和视频方向保持一致 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]; //获得要调整的设备输入对象 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(@"保存视频到相簿过程中发生错误,错误信息:%@",error.localizeddescription); } if (lastbackgroundtaskidentifier!=uibackgroundtaskinvalid) { [[uiapplication sharedapplication] endbackgroundtask:lastbackgroundtaskidentifier]; } nslog(@"成功保存视频到相簿."); }]; } #pragma mark - 通知 /** * 给输入设备添加通知 */ -(void)addnotificationtocapturedevice:(avcapturedevice *)capturedevice{ //注意添加区域改变捕获通知必须首先设置设备允许捕获 [self changedeviceproperty:^(avcapturedevice *capturedevice) { capturedevice.subjectareachangemonitoringenabled=yes; }]; nsnotificationcenter *notificationcenter= [nsnotificationcenter defaultcenter]; //捕获区域发生改变 [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]; } /** * 设备连接成功 * * @param notification 通知对象 */ -(void)deviceconnected:(nsnotification *)notification{ nslog(@"设备已连接..."); } /** * 设备连接断开 * * @param notification 通知对象 */ -(void)devicedisconnected:(nsnotification *)notification{ nslog(@"设备已断开."); } /** * 捕获区域改变 * * @param notification 通知对象 */ -(void)areachange:(nsnotification *)notification{ nslog(@"捕获区域改变..."); } /** * 会话出错 * * @param notification 通知对象 */ -(void)sessionruntimeerror:(nsnotification *)notification{ nslog(@"会话发生错误."); } #pragma mark - 私有方法 /** * 取得指定位置的摄像头 * * @param position 摄像头位置 * * @return 摄像头设备 */ -(avcapturedevice *)getcameradevicewithposition:(avcapturedeviceposition )position{ nsarray *cameras= [avcapturedevice deviceswithmediatype:avmediatypevideo]; for (avcapturedevice *camera in cameras) { if ([camera position]==position) { return camera; } } return nil; } /** * 改变设备属性的统一操作方法 * * @param propertychange 属性改变操作 */ -(void)changedeviceproperty:(propertychangeblock)propertychange{ avcapturedevice *capturedevice= [self.capturedeviceinput device]; nserror *error; //注意改变设备属性前一定要首先调用lockforconfiguration:调用完之后使用unlockforconfiguration方法解锁 if ([capturedevice lockforconfiguration:&error]) { propertychange(capturedevice); [capturedevice unlockforconfiguration]; }else{ nslog(@"设置设备属性过程发生错误,错误信息:%@",error.localizeddescription); } } /** * 设置闪光灯模式 * * @param flashmode 闪光灯模式 */ -(void)setflashmode:(avcaptureflashmode )flashmode{ [self changedeviceproperty:^(avcapturedevice *capturedevice) { if ([capturedevice isflashmodesupported:flashmode]) { [capturedevice setflashmode:flashmode]; } }]; } /** * 设置聚焦模式 * * @param focusmode 聚焦模式 */ -(void)setfocusmode:(avcapturefocusmode )focusmode{ [self changedeviceproperty:^(avcapturedevice *capturedevice) { if ([capturedevice isfocusmodesupported:focusmode]) { [capturedevice setfocusmode:focusmode]; } }]; } /** * 设置曝光模式 * * @param exposuremode 曝光模式 */ -(void)setexposuremode:(avcaptureexposuremode)exposuremode{ [self changedeviceproperty:^(avcapturedevice *capturedevice) { if ([capturedevice isexposuremodesupported:exposuremode]) { [capturedevice setexposuremode:exposuremode]; } }]; } /** * 设置聚焦点 * * @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坐标转化为摄像头坐标 cgpoint camerapoint= [self.capturevideopreviewlayer capturedevicepointofinterestforpoint:point]; [self setfocuscursorwithpoint:point]; [self focuswithmode:avcapturefocusmodeautofocus exposuremode:avcaptureexposuremodeautoexpose atpoint:camerapoint]; } /** * 设置聚焦光标位置 * * @param point 光标位置 */ -(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
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。