BDFaceBaseViewController.m 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530
  1. //
  2. // BDFaceBaseViewController.m
  3. // FaceSDKSample_IOS
  4. //
  5. // Created by 阿凡树 on 2017/5/23.
  6. // Copyright © 2017年 Baidu. All rights reserved.
  7. //
  8. #import "BDFaceBaseViewController.h"
  9. #import "BDFaceVideoCaptureDevice.h"
  10. #import "BDFaceImageUtils.h"
  11. #import "BDFaceRemindView.h"
  12. #import "BDFaceLogoView.h"
  13. #import "BDFaceLivingConfigModel.h"
  14. // 判断是否是ipad
  15. #define isPad ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad)
  16. // 判断iPhoneX
  17. #define IS_IPHONE_X ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(1125, 2436), [[UIScreen mainScreen] currentMode].size) && !isPad : NO)
  18. // 判断iPHoneXr
  19. #define IS_IPHONE_Xr ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(828, 1792), [[UIScreen mainScreen] currentMode].size) && !isPad : NO)
  20. // 判断iPhoneXs
  21. #define IS_IPHONE_Xs ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(1125, 2436), [[UIScreen mainScreen] currentMode].size) && !isPad : NO)
  22. // 判断iPhoneXs Max
  23. #define IS_IPHONE_Xs_Max ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(1242, 2688), [[UIScreen mainScreen] currentMode].size) && !isPad : NO)
  24. #define scaleValue 0.70
  25. #define scaleValueX 0.80
  26. #define ScreenRect [UIScreen mainScreen].bounds
  27. #define ScreenWidth [UIScreen mainScreen].bounds.size.width
  28. #define ScreenHeight [UIScreen mainScreen].bounds.size.height
  29. /**iPhone6s为标准,乘以宽的比例*/
  30. #define KScaleX(value) ((value)/375.0f * ScreenWidth)
  31. /**iPhone6s为标准,乘以高的比例*/
  32. #define KScaleY(value) ((value)/667.0f * ScreenHeight)
  33. @interface BDFaceBaseViewController () <CaptureDataOutputProtocol>
  34. //{
  35. // UIImageView * newImage;
  36. // BOOL isPaint;
  37. //}
  38. @property (nonatomic, readwrite, retain) BDFaceVideoCaptureDevice *videoCapture;
  39. @property (nonatomic, readwrite, retain) UILabel *remindLabel;
  40. @property (nonatomic, readwrite, retain) UIImageView *voiceImageView;
  41. @property (nonatomic, readwrite, retain) BDFaceRemindView * remindView;
  42. @property (nonatomic, readwrite, retain) UILabel * remindDetailLabel;
  43. // 超时相关控件
  44. @property (nonatomic, readwrite, retain) UIView *timeOutMainView;
  45. @property (nonatomic, readwrite, retain) UIImageView *timeOutImageView;
  46. @property (nonatomic, readwrite, retain) UILabel *timeOutLabel;
  47. @property (nonatomic, readwrite, retain) UIView *timeOutLine;
  48. @property (nonatomic, readwrite, retain) UIButton *timeOutRestartButton;
  49. @property (nonatomic, readwrite, retain) UILabel *timeOutRestartLabel;
  50. @property (nonatomic, readwrite, retain) UIView *timeOutLine2;
  51. @property (nonatomic, readwrite, retain) UIButton *timeOutRestartButton2;
  52. @property (nonatomic, readwrite, retain) UILabel *timeOutBackToMainLabel2;
  53. @end
  54. @implementation BDFaceBaseViewController
  55. - (void)dealloc
  56. {
  57. [[NSNotificationCenter defaultCenter] removeObserver:self];
  58. }
  59. - (void) setHasFinished:(BOOL)hasFinished {
  60. _hasFinished = hasFinished;
  61. if (hasFinished) {
  62. [self.videoCapture stopSession];
  63. self.videoCapture.delegate = nil;
  64. }
  65. }
  66. - (void)warningStatus:(WarningStatus)status warning:(NSString *)warning
  67. {
  68. __weak typeof(self) weakSelf = self;
  69. dispatch_async(dispatch_get_main_queue(), ^{
  70. if (status == PoseStatus) {
  71. [weakSelf.remindLabel setHidden:false];
  72. [weakSelf.remindView setHidden:false];
  73. [weakSelf.remindDetailLabel setHidden:false];
  74. weakSelf.remindDetailLabel.text = warning;
  75. weakSelf.remindLabel.text = @"请保持正脸";
  76. }else if (status == occlusionStatus) {
  77. [weakSelf.remindLabel setHidden:false];
  78. [weakSelf.remindView setHidden:true];
  79. [weakSelf.remindDetailLabel setHidden:false];
  80. weakSelf.remindDetailLabel.text = warning;
  81. weakSelf.remindLabel.text = @"脸部有遮挡";
  82. }else {
  83. [weakSelf.remindLabel setHidden:false];
  84. [weakSelf.remindView setHidden:true];
  85. [weakSelf.remindDetailLabel setHidden:true];
  86. weakSelf.remindLabel.text = warning;
  87. }
  88. });
  89. }
  90. - (void)singleActionSuccess:(BOOL)success
  91. {
  92. __weak typeof(self) weakSelf = self;
  93. dispatch_async(dispatch_get_main_queue(), ^{
  94. if (success) {
  95. }else {
  96. }
  97. });
  98. }
  99. - (void)viewDidLoad {
  100. [super viewDidLoad];
  101. // NSString* licensePath = [NSString stringWithFormat:@"%@.%@", FACE_LICENSE_NAME, FACE_LICENSE_SUFFIX ];
  102. // [[FaceSDKManager sharedInstance] setLicenseID:FACE_LICENSE_ID andLocalLicenceFile:licensePath andRemoteAuthorize:false];
  103. // 用于播放视频流
  104. if (IS_IPHONE_X || IS_IPHONE_Xr || IS_IPHONE_Xs || IS_IPHONE_Xs_Max) {
  105. self.previewRect = CGRectMake(ScreenWidth*(1-scaleValueX)/2.0, ScreenHeight*(1-scaleValueX)/2.0, ScreenWidth*scaleValueX, ScreenHeight*scaleValueX);
  106. } else {
  107. self.previewRect = CGRectMake(ScreenWidth*(1-scaleValue)/2.0, ScreenHeight*(1-scaleValue)/2.0, ScreenWidth*scaleValue, ScreenHeight*scaleValue);
  108. }
  109. // 超时的view初始化,但是不添加到当前view内
  110. // 超时的最底层view,大小和屏幕大小一致,为了突出弹窗的view的效果,背景为灰色,0.7的透视度
  111. _timeOutMainView = [[UIView alloc] init];
  112. _timeOutMainView.frame = ScreenRect;
  113. _timeOutMainView.alpha = 0.7;
  114. _timeOutMainView.backgroundColor = [UIColor grayColor];
  115. // 弹出的主体view
  116. self.timeOutView = [[UIView alloc] init];
  117. self.timeOutView.frame = CGRectMake(KScaleX(20), KScaleY(179.3), ScreenWidth-KScaleX(40), KScaleY(281.3));
  118. self.timeOutView.backgroundColor = [UIColor colorWithRed:255 / 255.0 green:255 / 255.0 blue:255 / 255.0 alpha:1 / 1.0];
  119. self.timeOutView.layer.cornerRadius = 7.5;
  120. // 超时的image
  121. _timeOutImageView = [[UIImageView alloc] init];
  122. _timeOutImageView.frame = CGRectMake((ScreenWidth-76) / 2, KScaleY(217.3), 76, 76);
  123. _timeOutImageView.image = [UIImage imageNamed:@"icon_overtime"];
  124. // 超时的label
  125. _timeOutLabel = [[UILabel alloc] init];
  126. _timeOutLabel.frame = CGRectMake(KScaleX(40), KScaleY(309.3), ScreenWidth-KScaleX(80), 22);
  127. _timeOutLabel.text = @"人脸采集超时";
  128. _timeOutLabel.textAlignment = NSTextAlignmentCenter;
  129. _timeOutLabel.font = [UIFont fontWithName:@"PingFangSC-Medium" size:18];
  130. _timeOutLabel.textColor = [UIColor colorWithRed:0 / 255.0 green:0 / 255.0 blue:0 / 255.0 alpha:1 / 1.0];
  131. // 区分线
  132. _timeOutLine = [[UIView alloc] init];
  133. _timeOutLine.frame = CGRectMake((ScreenWidth-320) / 2, 361.2, 320, 0.3);
  134. _timeOutLine.backgroundColor = [UIColor colorWithRed:255 / 255.0 green:255 / 255.0 blue:255 / 255.0 alpha:1 / 1.0];
  135. // 重新开始采集button
  136. _timeOutRestartButton = [[UIButton alloc] initWithFrame:CGRectMake((ScreenWidth-320)/2, KScaleY(376), 320, 18)];
  137. [_timeOutRestartButton addTarget:self action:@selector(reStart:) forControlEvents:UIControlEventTouchUpInside];
  138. // 重新采集的文字label
  139. _timeOutRestartLabel = [[UILabel alloc] init];
  140. _timeOutRestartLabel.frame = CGRectMake((ScreenWidth-72) / 2, KScaleY(376.3), 72, 18);
  141. _timeOutRestartLabel.text = @"重新采集";
  142. _timeOutRestartLabel.font = [UIFont fontWithName:@"PingFangSC-Medium" size:18];
  143. _timeOutRestartLabel.textColor = [UIColor colorWithRed:0 / 255.0 green:186 / 255.0 blue:242 / 255.0 alpha:1 / 1.0];
  144. // 区分线
  145. _timeOutLine2 = [[UIView alloc] init];
  146. _timeOutLine2.frame = CGRectMake((ScreenWidth-320) / 2, 409.2, 320, 0.3);
  147. _timeOutLine2.backgroundColor = [UIColor colorWithRed:255 / 255.0 green:255 / 255.0 blue:255 / 255.0 alpha:1 / 1.0];
  148. // // 回到首页的button
  149. // _timeOutRestartButton2 = [[UIButton alloc] initWithFrame:CGRectMake((ScreenWidth-320)/2, KScaleY(424), 320, 18)];
  150. // [_timeOutRestartButton2 addTarget:self action:@selector(backToPreView:) forControlEvents:UIControlEventTouchUpInside];
  151. //
  152. // // 回到首页的label
  153. // _timeOutBackToMainLabel2 = [[UILabel alloc] init];
  154. // _timeOutBackToMainLabel2.frame = CGRectMake((ScreenWidth-72) / 2, KScaleY(424.3), 72, 18);
  155. // _timeOutBackToMainLabel2.text = @"回到首页";
  156. // _timeOutBackToMainLabel2.font = [UIFont fontWithName:@"PingFangSC-Medium" size:18];
  157. // _timeOutBackToMainLabel2.textColor = [UIColor colorWithRed:102 / 255.0 green:102 / 255.0 blue:102 / 255.0 alpha:1 / 1.0];
  158. // 初始化相机处理类
  159. self.videoCapture = [[BDFaceVideoCaptureDevice alloc] init];
  160. self.videoCapture.delegate = self;
  161. // 用于展示视频流的imageview
  162. self.displayImageView = [[UIImageView alloc] initWithFrame:self.previewRect];
  163. self.displayImageView.contentMode = UIViewContentModeScaleAspectFill;
  164. [self.view addSubview:self.displayImageView];
  165. CGRect circleRect =CGRectMake(ScreenWidth*(1-scaleValue)/2.0 , 175*ScreenHeight/667, ScreenWidth*scaleValue, ScreenWidth*scaleValue);
  166. // 画圈和圆形遮罩
  167. self.detectRect = CGRectMake(circleRect.origin.x , circleRect.origin.y, circleRect.size.width, circleRect.size.height*5/4);
  168. CGPoint centerPoint = CGPointMake(CGRectGetMidX(circleRect), CGRectGetMidY(circleRect));
  169. //创建一个View
  170. UIView *maskView = [[UIView alloc] initWithFrame:ScreenRect];
  171. maskView.backgroundColor = [UIColor whiteColor];
  172. maskView.alpha = 1;
  173. [self.view addSubview:maskView];
  174. //贝塞尔曲线 画一个带有圆角的矩形
  175. UIBezierPath *bpath = [UIBezierPath bezierPathWithRoundedRect:ScreenRect cornerRadius:0];
  176. //贝塞尔曲线 画一个圆形
  177. [bpath appendPath:[UIBezierPath bezierPathWithArcCenter:centerPoint radius:ScreenWidth*scaleValue / 2 startAngle:0 endAngle:2 * M_PI clockwise:NO]];
  178. //创建一个CAShapeLayer 图层
  179. CAShapeLayer *shapeLayer = [CAShapeLayer layer];
  180. shapeLayer.path = bpath.CGPath;
  181. // 添加图层蒙板
  182. maskView.layer.mask = shapeLayer;
  183. // 进度条view,活体检测页面
  184. CGRect circleProgressRect = CGRectMake(CGRectGetMinX(circleRect) - 13.7, CGRectGetMinY(circleRect) - 13.7, CGRectGetWidth(circleRect) + (13.7 * 2), CGRectGetHeight(circleRect) + (13.7 * 2));
  185. self.circleProgressView = [[BDFaceCycleProgressView alloc] initWithFrame:circleProgressRect];
  186. // 动作活体动画
  187. self.remindAnimationView = [[BDFaceRemindAnimationView alloc] initWithFrame:circleRect];
  188. // 提示框(动作)
  189. self.remindLabel = [[UILabel alloc] init];
  190. self.remindLabel.frame = CGRectMake(0, 103.3, ScreenWidth, 22);
  191. self.remindLabel.textAlignment = NSTextAlignmentCenter;
  192. self.remindLabel.textColor = [UIColor colorWithRed:0 / 255.0 green:0 / 255.0 blue:0 / 255.0 alpha:1 / 1.0];
  193. self.remindLabel.font = [UIFont boldSystemFontOfSize:22];
  194. [self.view addSubview:self.remindLabel];
  195. // 提示label(遮挡等问题)
  196. self.remindDetailLabel = [[UILabel alloc] init];
  197. self.remindDetailLabel.frame = CGRectMake(0, 139.3, ScreenWidth, 16);
  198. self.remindDetailLabel.font = [UIFont systemFontOfSize:16];
  199. self.remindDetailLabel.textColor = [UIColor colorWithRed:102 / 255.0 green:102 / 255.0 blue:102 / 255.0 alpha:1 / 1.0];
  200. self.remindDetailLabel.textAlignment = NSTextAlignmentCenter;
  201. [self.view addSubview:self.remindDetailLabel];
  202. [self.remindDetailLabel setHidden:true];
  203. UIButton *backButton = [[UIButton alloc] init];
  204. backButton.frame = CGRectMake(23.3, 43.3, 20, 20);
  205. [backButton setImage:[UIImage imageNamed:@"icon_titlebar_close"] forState:UIControlStateNormal];
  206. [backButton addTarget:self action:@selector(closeAction) forControlEvents:UIControlEventTouchUpInside];
  207. [self.view addSubview:backButton];
  208. // 音量imageView,可动态播放图片
  209. _voiceImageView = [[UIImageView alloc] init];
  210. _voiceImageView.frame = CGRectMake((ScreenWidth-22-20), 42.7, 22, 22);
  211. _voiceImageView.animationImages = [NSArray arrayWithObjects:
  212. [UIImage imageNamed:@"icon_titlebar_voice1"],
  213. [UIImage imageNamed:@"icon_titlebar_voice2"], nil];
  214. _voiceImageView.animationDuration = 2;
  215. _voiceImageView.animationRepeatCount = 0;
  216. NSNumber *soundMode = [[NSUserDefaults standardUserDefaults] objectForKey:@"SoundMode"];
  217. if (soundMode.boolValue){
  218. [_voiceImageView startAnimating];
  219. } else {
  220. _voiceImageView.image = [UIImage imageNamed:@"icon_titlebar_voice_close"];
  221. }
  222. _voiceImageView.userInteractionEnabled = YES;
  223. UITapGestureRecognizer *changeVoidceSet = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(changeVoidceSet:)];
  224. [_voiceImageView addGestureRecognizer:changeVoidceSet];
  225. [self.view addSubview:_voiceImageView];
  226. // 底部logo部分
  227. UIImageView *logoImageView = [[UIImageView alloc] init];
  228. logoImageView.frame = CGRectMake(0, CGRectGetMaxY(self.view.frame) - 221, ScreenWidth, 221);
  229. logoImageView.image = [UIImage imageNamed:@"bg_bottom_pattern"];
  230. [self.view addSubview:logoImageView];
  231. // 设置logo,底部的位置和大小,实例化显示
  232. BDFaceLogoView* logoView = [[BDFaceLogoView alloc] initWithFrame:CGRectMake(0, (ScreenHeight-15-12), ScreenWidth, 12)];
  233. [self.view addSubview:logoView];
  234. // 监听重新返回APP
  235. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onAppWillResignAction) name:UIApplicationWillResignActiveNotification object:nil];
  236. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onAppBecomeActive) name:UIApplicationDidBecomeActiveNotification object:nil];
  237. if (![[FaceSDKManager sharedInstance] canWork]){
  238. NSLog(@"授权失败,请检测ID 和 授权文件是否可用");
  239. return;
  240. }
  241. // 初始化SDK配置参数,可使用默认配置
  242. // 设置最小检测人脸阈值
  243. // [[FaceSDKManager sharedInstance] setMinFaceSize:100];
  244. // // 设置截取人脸图片宽
  245. // [[FaceSDKManager sharedInstance] setCropFaceSizeWidth:0];
  246. // // 设置截取人脸图片高
  247. // [[FaceSDKManager sharedInstance] setCropFaceSizeHeight:0];
  248. // // 设置人脸遮挡阀值
  249. // [[FaceSDKManager sharedInstance] setOccluThreshold:0.5];
  250. // // 设置亮度阀值
  251. // [[FaceSDKManager sharedInstance] setMinIllumThreshold:40];
  252. // [[FaceSDKManager sharedInstance] setMaxIllumThreshold:240];
  253. // // 设置图像模糊阀值
  254. // [[FaceSDKManager sharedInstance] setBlurThreshold:0.7];
  255. // // 设置头部姿态角度
  256. // [[FaceSDKManager sharedInstance] setEulurAngleThrPitch:10 yaw:10 roll:10];
  257. // // 设置人脸检测精度阀值
  258. // [[FaceSDKManager sharedInstance] setNotFaceThreshold:0.6];
  259. // // 设置抠图的缩放倍数
  260. // [[FaceSDKManager sharedInstance] setCropEnlargeRatio:1.0];
  261. // // 设置照片采集张数
  262. // [[FaceSDKManager sharedInstance] setMaxCropImageNum:1];
  263. // // 设置超时时间
  264. // [[FaceSDKManager sharedInstance] setConditionTimeout:15];
  265. // // 设置开启口罩检测,非动作活体检测可以采集戴口罩图片
  266. // [[FaceSDKManager sharedInstance] setIsCheckMouthMask:true];
  267. // // 设置开启口罩检测情况下,非动作活体检测口罩过滤阈值,默认0.8 不需要修改
  268. // [[FaceSDKManager sharedInstance] setMouthMaskThreshold:0.8f];
  269. // // 设置原始图缩放比例
  270. // [[FaceSDKManager sharedInstance] setImageWithScale:0.8f];
  271. // // 设置图片加密类型,type=0 基于base64 加密;type=1 基于百度安全算法加密
  272. // [[FaceSDKManager sharedInstance] setImageEncrypteType:0];
  273. // // 初始化SDK功能函数
  274. // [[FaceSDKManager sharedInstance] initCollect];
  275. // [[FaceSDKManager sharedInstance] setMinRect:0.4];
  276. /*
  277. 调试需要时可以打开以下注释
  278. 蓝色框:检测框(视频流返回的位置)
  279. 黄色框:采集框(人脸在采集框中都可以被识别,为了容错设置的宽松了一点)
  280. 圆框:采集显示框(人脸应该放置的检测位置)
  281. 绿色框:人脸最小框(通过最小框判定人脸是否过远,按照黄色框百分比:0.4宽)
  282. // UIImageView* circleImage= [[UIImageView alloc]init];
  283. // circleImage = [self creatRectangle:circleImage withRect:circleRect withcolor:[UIColor redColor]];
  284. // [self.view addSubview:circleImage];
  285. //
  286. // UIImageView* previewImage= [[UIImageView alloc]init];
  287. // previewImage = [self creatRectangle:previewImage withRect:self.previewRect withcolor:[UIColor yellowColor]];
  288. // [self.view addSubview:previewImage];
  289. //
  290. // UIImageView* detectImage= [[UIImageView alloc]init];
  291. // detectImage = [self creatRectangle:detectImage withRect:self.detectRect withcolor:[UIColor blueColor]];
  292. // [self.view addSubview:detectImage];
  293. //
  294. // CGRect _minRect = CGRectMake(CGRectGetMinX(self.detectRect)+CGRectGetWidth(self.detectRect)*(1-[[FaceSDKManager sharedInstance] minRectScale])/2, CGRectGetMinY(self.detectRect)+CGRectGetWidth(self.detectRect)*(1-[[FaceSDKManager sharedInstance] minRectScale])/2, CGRectGetWidth(self.detectRect)*[[FaceSDKManager sharedInstance] minRectScale], CGRectGetWidth(self.detectRect)*[[FaceSDKManager sharedInstance] minRectScale]);
  295. // UIImageView* minImage= [[UIImageView alloc]init];
  296. // minImage = [self creatRectangle:minImage withRect:_minRect withcolor:[UIColor greenColor]];
  297. // [self.view addSubview:minImage];
  298. */
  299. }
  300. #pragma mark-绘框方法
  301. - (UIImageView *)creatRectangle:(UIImageView *)imageView withRect:(CGRect) rect withcolor:(UIColor *)color{
  302. CAShapeLayer *lineLayer = [CAShapeLayer layer];
  303. //创建需要画线的视图
  304. UIBezierPath *linePath = [UIBezierPath bezierPath];
  305. //起点
  306. float x = rect.origin.x;
  307. float y = rect.origin.y;
  308. float W = rect.size.width;
  309. float H = rect.size.height;
  310. [linePath moveToPoint:CGPointMake(x, y)];
  311. //其他点
  312. [linePath addLineToPoint:CGPointMake(x + W, y)];
  313. [linePath addLineToPoint:CGPointMake(x + W, y + H)];
  314. [linePath addLineToPoint:CGPointMake(x, y + H)];
  315. [linePath addLineToPoint:CGPointMake(x, y)];
  316. lineLayer.lineWidth = 2;
  317. lineLayer.strokeColor = color.CGColor;
  318. lineLayer.path = linePath.CGPath;
  319. lineLayer.fillColor = nil; // 默认为blackColor
  320. imageView.layer.sublayers = nil;
  321. [imageView.layer addSublayer:lineLayer];
  322. return imageView;
  323. }
  324. - (void)isTimeOut:(BOOL)isOrNot {
  325. if (isOrNot){
  326. // 加载超时的view
  327. [self outTimeViewLoad];
  328. }
  329. }
  330. - (void)outTimeViewLoad{
  331. // 显示超时view,并停止视频流工作
  332. self.remindLabel.text = @"";
  333. self.remindDetailLabel.text = @"";
  334. self.videoCapture.runningStatus = NO;
  335. [self.videoCapture stopSession];
  336. [self.view addSubview:_timeOutMainView];
  337. [self.view addSubview:_timeOutView];
  338. [self.view addSubview:_timeOutImageView];
  339. [self.view addSubview:_timeOutLabel];
  340. [self.view addSubview:_timeOutRestartButton];
  341. [self.view addSubview:_timeOutLine];
  342. [self.view addSubview:_timeOutRestartLabel];
  343. [self.view addSubview:_timeOutLine2];
  344. [self.view addSubview:_timeOutRestartButton2];
  345. [self.view addSubview:_timeOutBackToMainLabel2];
  346. }
  347. - (void)outTimeViewUnload{
  348. // 关闭超时的view,恢复视频流工作
  349. self.videoCapture.runningStatus = YES;
  350. [self.videoCapture startSession];
  351. [_timeOutMainView removeFromSuperview];
  352. [_timeOutView removeFromSuperview];
  353. [_timeOutImageView removeFromSuperview];
  354. [_timeOutLabel removeFromSuperview];
  355. [_timeOutRestartButton removeFromSuperview];
  356. [_timeOutLine removeFromSuperview];
  357. [_timeOutRestartLabel removeFromSuperview];
  358. [_timeOutLine2 removeFromSuperview];
  359. [_timeOutBackToMainLabel2 removeFromSuperview];
  360. [_timeOutRestartButton2 removeFromSuperview];
  361. }
  362. - (void)viewDidDisappear:(BOOL)animated {
  363. [super viewDidDisappear:animated];
  364. self.hasFinished = YES;
  365. self.videoCapture.runningStatus = NO;
  366. }
  367. - (void)viewWillAppear:(BOOL)animated {
  368. [super viewWillAppear:animated];
  369. _hasFinished = NO;
  370. self.videoCapture.runningStatus = YES;
  371. [self.videoCapture startSession];
  372. }
  373. - (void)didReceiveMemoryWarning {
  374. [super didReceiveMemoryWarning];
  375. // Dispose of any resources that can be recreated.
  376. }
  377. - (void)faceProcesss:(UIImage *)image {
  378. }
  379. - (void)closeAction {
  380. _hasFinished = YES;
  381. self.videoCapture.runningStatus = NO;
  382. [self dismissViewControllerAnimated:YES completion:nil];
  383. }
  384. #pragma mark - ButtonFunction
  385. - (IBAction)reStart:(UIButton *)sender{
  386. // 对应页面去补充
  387. dispatch_async(dispatch_get_main_queue(), ^{
  388. [self outTimeViewUnload];
  389. });
  390. // 调用相应的部分设置
  391. [self selfReplayFunction];
  392. }
  393. - (void)selfReplayFunction{
  394. // 相应的功能在采集/检测时候写
  395. }
  396. - (IBAction)backToPreView:(UIButton *)sender{
  397. [self dismissViewControllerAnimated:YES completion:nil];
  398. }
  399. #pragma mark - Notification
  400. - (void)onAppWillResignAction {
  401. _hasFinished = YES;
  402. }
  403. - (void)onAppBecomeActive {
  404. _hasFinished = NO;
  405. }
  406. #pragma mark - voiceImageView tap
  407. - (void)changeVoidceSet:(UITapGestureRecognizer *)sender {
  408. NSNumber *soundMode = [[NSUserDefaults standardUserDefaults] objectForKey:@"SoundMode"];
  409. NSLog(@"点击");
  410. if (soundMode.boolValue && _voiceImageView.animating) {
  411. [_voiceImageView stopAnimating];
  412. _voiceImageView.image = [UIImage imageNamed:@"icon_titlebar_voice_close"];
  413. // 之前是开启的,点击后关闭
  414. [[NSUserDefaults standardUserDefaults] setObject:@(NO) forKey:@"SoundMode"];
  415. // 活体声音
  416. [IDLFaceLivenessManager sharedInstance].enableSound = NO;
  417. // 图像采集声音
  418. [IDLFaceDetectionManager sharedInstance].enableSound = NO;
  419. } else {
  420. [_voiceImageView startAnimating];
  421. [[NSUserDefaults standardUserDefaults] setObject:@(YES) forKey:@"SoundMode"];
  422. // 活体声音
  423. [IDLFaceLivenessManager sharedInstance].enableSound = YES;
  424. // 图像采集声音
  425. [IDLFaceDetectionManager sharedInstance].enableSound = YES;
  426. }
  427. }
  428. #pragma mark - CaptureDataOutputProtocol
  429. - (void)captureOutputSampleBuffer:(UIImage *)image {
  430. if (_hasFinished) {
  431. return;
  432. }
  433. __weak typeof(self) weakSelf = self;
  434. dispatch_async(dispatch_get_main_queue(), ^{
  435. weakSelf.displayImageView.image = image;
  436. });
  437. [self faceProcesss:image];
  438. }
  439. - (void)captureError {
  440. NSString *errorStr = @"出现未知错误,请检查相机设置";
  441. AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
  442. if(authStatus == AVAuthorizationStatusRestricted || authStatus == AVAuthorizationStatusDenied){
  443. errorStr = @"相机权限受限,请在设置中启用";
  444. }
  445. __weak typeof(self) weakSelf = self;
  446. dispatch_async(dispatch_get_main_queue(), ^{
  447. UIAlertController* alert = [UIAlertController alertControllerWithTitle:nil message:errorStr preferredStyle:UIAlertControllerStyleAlert];
  448. UIAlertAction* action = [UIAlertAction actionWithTitle:@"知道啦" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
  449. NSLog(@"知道啦");
  450. }];
  451. [alert addAction:action];
  452. UIViewController* fatherViewController = weakSelf.presentingViewController;
  453. [weakSelf dismissViewControllerAnimated:YES completion:^{
  454. [fatherViewController presentViewController:alert animated:YES completion:nil];
  455. }];
  456. });
  457. }
  458. @end