ios6 - Toggle camera using AVFoundation iOS 6 -
i want toggle camera using avfoundation. here code have subclass of nsobject
@interface capturesessionmanager : nsobject
@property (retain) avcapturevideopreviewlayer *previewlayer; @property (retain) avcapturesession *capturesession; @property (retain) avcapturestillimageoutput *stillimageoutput; @property (nonatomic, retain) uiimage *stillimage; in @implementation capturesessionmanager
- (id)init { if ((self = [super init])) { [self setcapturesession:[[avcapturesession alloc] init]]; } return self; } - (void)addvideopreviewlayer { [self setpreviewlayer:[[[avcapturevideopreviewlayer alloc] initwithsession:[self capturesession]] autorelease]]; [[self previewlayer] setvideogravity:avlayervideogravityresizeaspectfill]; } - (void)addvideoinputfrontcamera:(bool)front { nsarray *devices = [avcapturedevice devices]; avcapturedevice *frontcamera; avcapturedevice *backcamera; (avcapturedevice *device in devices) { nslog(@"device name: %@", [device localizedname]); if ([device hasmediatype:avmediatypevideo]) { if ([device position] == avcapturedevicepositionback) { nslog(@"device position : back"); backcamera = device; } else { nslog(@"device position : front"); frontcamera = device; } } } nserror *error = nil; if (front) { avcapturedeviceinput *frontfacingcameradeviceinput = [avcapturedeviceinput deviceinputwithdevice:frontcamera error:&error]; if (!error) { if ([[self capturesession] canaddinput:frontfacingcameradeviceinput]) { [[self capturesession] addinput:frontfacingcameradeviceinput]; } else { nslog(@"couldn't add front facing video input"); } } } else { avcapturedeviceinput *backfacingcameradeviceinput = [avcapturedeviceinput deviceinputwithdevice:backcamera error:&error]; if (!error) { if ([[self capturesession] canaddinput:backfacingcameradeviceinput]) { [[self capturesession] addinput:backfacingcameradeviceinput]; } else { nslog(@"couldn't add facing video input"); } } } } - (void)addstillimageoutput { [self setstillimageoutput:[[[avcapturestillimageoutput alloc] init] autorelease]]; nsdictionary *outputsettings = [[nsdictionary alloc] initwithobjectsandkeys:avvideocodecjpeg,avvideocodeckey,nil]; [[self stillimageoutput] setoutputsettings:outputsettings]; avcaptureconnection *videoconnection = nil; (avcaptureconnection *connection in [[self stillimageoutput] connections]) { (avcaptureinputport *port in [connection inputports]) { if ([[port mediatype] isequal:avmediatypevideo] ) { videoconnection = connection; break; } } if (videoconnection) { break; } } [[self capturesession] addoutput:[self stillimageoutput]]; } - (void)capturestillimage { avcaptureconnection *videoconnection = nil; (avcaptureconnection *connection in [[self stillimageoutput] connections]) { (avcaptureinputport *port in [connection inputports]) { if ([[port mediatype] isequal:avmediatypevideo]) { videoconnection = connection; break; } } if (videoconnection) { break; } } nslog(@"about request capture from: %@", [self stillimageoutput]); [[self stillimageoutput] capturestillimageasynchronouslyfromconnection:videoconnection completionhandler:^(cmsamplebufferref imagesamplebuffer, nserror *error) { cfdictionaryref exifattachments = cmgetattachment(imagesamplebuffer, kcgimagepropertyexifdictionary, null); if (exifattachments) { nslog(@"attachements: %@", exifattachments); } else { nslog(@"no attachments"); } nsdata *imagedata = [avcapturestillimageoutput jpegstillimagensdatarepresentation:imagesamplebuffer]; uiimage *image = [[uiimage alloc] initwithdata:imagedata]; [self setstillimage:image]; [image release]; [[nsnotificationcenter defaultcenter] postnotificationname:kimagecapturedsuccessfully object:nil]; }]; } - (void)dealloc { [[self capturesession] stoprunning]; [previewlayer release], previewlayer = nil; [capturesession release], capturesession = nil; [stillimageoutput release], stillimageoutput = nil; [stillimage release], stillimage = nil; [super dealloc]; } -(void)togglecamera:(bool)front { nsarray *devices = [avcapturedevice devices]; avcapturedevice *frontcamera; avcapturedevice *backcamera; (avcapturedevice *device in devices) { nslog(@"device name: %@", [device localizedname]); if ([device hasmediatype:avmediatypevideo]) { if ([device position] == avcapturedevicepositionback) { nslog(@"device position : back"); backcamera = device; } else { nslog(@"device position : front"); frontcamera = device; } } } [[self capturesession] beginconfiguration]; nserror *error = nil; avcapturedeviceinput *frontfacingcameradeviceinput = [avcapturedeviceinput deviceinputwithdevice:frontcamera error:&error]; avcapturedeviceinput *backfacingcameradeviceinput = [avcapturedeviceinput deviceinputwithdevice:backcamera error:&error]; if (front) { [[self capturesession] removeinput:backfacingcameradeviceinput]; if (!error) { if ([[self capturesession] canaddinput:frontfacingcameradeviceinput]) { [[self capturesession] addinput:frontfacingcameradeviceinput]; } else { nslog(@"couldn't add front facing video input"); } [[self capturesession] addinput:frontfacingcameradeviceinput]; } } else { [[self capturesession] removeinput:frontfacingcameradeviceinput]; if (!error) { if ([[self capturesession] canaddinput:backfacingcameradeviceinput]) { [[self capturesession] addinput:backfacingcameradeviceinput]; } else { nslog(@"couldn't add facing video input"); } [[self capturesession] addinput:backfacingcameradeviceinput]; } } [[self capturesession] commitconfiguration]; } in viewcontroller , have
@property (retain) capturesessionmanager *capturemanager; @property (nonatomic,readwrite) bool isfrontcameraselected; - (void)viewdidload { self.isfrontcameraselected = no; [self setcapturemanager:[[[capturesessionmanager alloc] init] autorelease]]; [[self capturemanager] addvideoinputfrontcamera:self.isfrontcameraselected]; // set yes front camera, no camera [[self capturemanager] addstillimageoutput]; [[self capturemanager] addvideopreviewlayer]; cgrect layerrect = [[[self innerview] layer] bounds]; [[[self capturemanager] previewlayer] setbounds:layerrect]; [[[self capturemanager] previewlayer] setposition:cgpointmake(cgrectgetmidx(layerrect),cgrectgetmidy(layerrect))]; [[[self innerview] layer] addsublayer:[[self capturemanager] previewlayer]]; uiimageview *overlayimageview = [[uiimageview alloc] initwithimage:[uiimage imagenamed:@"overlaygraphic.png"]]; [overlayimageview setframe:cgrectmake(30, 60, 260, 260)]; [[self innerview] addsubview:overlayimageview]; [overlayimageview release]; uibutton *overlaybutton3 = [uibutton buttonwithtype:uibuttontypecustom]; [overlaybutton3 setimage:[uiimage imagenamed:@"camera.png"] forstate:uicontrolstatenormal]; [overlaybutton3 setframe:cgrectmake(130, 330, 60, 30)]; [overlaybutton3 addtarget:self action:@selector(innerscanbuttonpressed) forcontrolevents:uicontroleventtouchupinside]; [[self innerview] addsubview:overlaybutton3]; uibutton *cameraselection = [uibutton buttonwithtype:uibuttontypecustom]; [cameraselection setimage:[uiimage imagenamed:@"camera.png"] forstate:uicontrolstatenormal]; [cameraselection setframe:cgrectmake(260, 30, 60, 30)]; [cameraselection addtarget:self action:@selector(cameraselectiontapped:) forcontrolevents:uicontroleventtouchupinside]; [[self innerview] addsubview:cameraselection]; [[nsnotificationcenter defaultcenter] addobserver:self selector:@selector(saveimagetophotoalbum) name:kimagecapturedsuccessfully object:nil]; [[capturemanager capturesession] startrunning]; } - (void)innerscanbuttonpressed { [[self scanninglabel] sethidden:no]; [[self capturemanager] capturestillimage]; } -(void)cameraselectiontapped:(id)sender { [[self capturemanager] togglecamera:self.isfrontcameraselected]; } when click on togglecamera button , crashes below error
couldn't add facing video input *** terminating app due uncaught exception 'nsinvalidargumentexception', reason: '*** multiple audio/video avcaptureinputs not supported.' *** first throw call stack: (0x38f2f2a3 0x3725997f 0x39aff977 0x39aff091 0xe943d 0xe7875 0x3a4de0a5 0x3a4de057 0x3a4de035 0x3a4dd8eb 0x3a4ddde1 0x3a4065f1 0x3a3f3801 0x3a3f311b 0x37cad5a3 0x37cad1d3 0x38f04173 0x38f04117 0x38f02f99 0x38e75ebd 0x38e75d49 0x37cac2eb 0x3a4472f9 0xdf1ab 0x36324b20) i want add toggle feature user can use front / camera click photo.
any kind of highly appreciated. in advance.
you're trying add same device input twice in code:
if (!error) { if ([[self capturesession] canaddinput:frontfacingcameradeviceinput]) { [[self capturesession] addinput:frontfacingcameradeviceinput]; } else { nslog(@"couldn't add front facing video input"); } [[self capturesession] addinput:frontfacingcameradeviceinput]; } take out second call addinput on both front , logic.
Comments
Post a Comment