ios - How to avoid blocking the UI when using the iPhone camera via AVFoundation? -
i trying embed simple view in iphone application take quick snapshots. works fine facing issues cameras startup-time. in apple sample project avcapturesession's -startrunning not getting executed on main thread, seems necessary. setting capture session during view's initialization starting in separate thread. add avcapturevideopreviewlayer in -didmovetosuperview. everything's fine without multithreading (the ui blocked second) gcd ui works, takes way long ui 'unfreeze' or preview shown.
how can deal camera's startup delay in reliable way, without blocking main thread (the delay not problem)?
i hope guys understand problem :d
thanks in advance!
btw: here proof-of-concept-project (without gcd) reusing app: http://github.com/dariolass/quickshotview
so figured out myself. code works me , produces least ui freezing:
- (void)willmovetosuperview:(uiview *)newsuperview { //capture session setup avcapturedeviceinput *newvideoinput = [[avcapturedeviceinput alloc] initwithdevice:self.rearcamera error:nil]; avcapturestillimageoutput *newstillimageoutput = [[avcapturestillimageoutput alloc] init]; nsdictionary *outputsettings = [[nsdictionary alloc] initwithobjectsandkeys: avvideocodecjpeg, avvideocodeckey, nil]; [newstillimageoutput setoutputsettings:outputsettings]; avcapturesession *newcapturesession = [[avcapturesession alloc] init]; if ([newcapturesession canaddinput:newvideoinput]) { [newcapturesession addinput:newvideoinput]; } if ([newcapturesession canaddoutput:newstillimageoutput]) { [newcapturesession addoutput:newstillimageoutput]; self.stillimageoutput = newstillimageoutput; self.capturesession = newcapturesession; } // -startrunning return when session started (-> camera ready) dispatch_queue_t layerq = dispatch_queue_create("layerq", null); dispatch_async(layerq, ^{ [self.capturesession startrunning]; avcapturevideopreviewlayer *prevlayer = [[avcapturevideopreviewlayer alloc]initwithsession:self.capturesession]; prevlayer.frame = self.previewlayerframe; prevlayer.maskstobounds = yes; prevlayer.videogravity = avlayervideogravityresizeaspectfill; prevlayer.cornerradius = preview_layer_edge_radius; //to make sure not modifying ui on thread other main thread, use dispatch_async w/ dispatch_get_main_queue dispatch_async(dispatch_get_main_queue(), ^{ [self.layer insertsublayer:prevlayer atindex:0]; }); }); }
Comments
Post a Comment