Zooming while capturing video using AVCapture in iOS - ios7

I am using AVCapture to capture video and save it. But I need to provide zooming option like pinch to zoom or through a zoom button. Also video should be saved in exactly in same manner in which it is being displayed, I mean when zoomed in, it should be saved zoomed. Any help, Link is appreciated. My code for setting up AVCapture session is:
- (void)setupAVCapture{
session = [[AVCaptureSession alloc] init];
session.automaticallyConfiguresApplicationAudioSession=YES;
[session beginConfiguration];
session.sessionPreset = AVCaptureSessionPresetMedium;
AVCaptureVideoPreviewLayer *captureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session];
captureVideoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
captureVideoPreviewLayer.frame = self.view.bounds;
[self.view.layer addSublayer:captureVideoPreviewLayer];
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
NSError *error = nil;
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
if (!input) {
// Handle the error appropriately.
NSLog(#"ERROR: trying to open camera: %#", error);
}
[session addInput:input];
movieFileOutput = [[AVCaptureMovieFileOutput alloc] init];
[session addOutput:movieFileOutput];
[session commitConfiguration];
[session startRunning];
}

I faced the same problem also, and I have solved it using these two steps:
Add a PinchGestureRecognizer event something like that in your Camera Preview View Controller
- (IBAction)handlePinchGesture:(UIPinchGestureRecognizer *)gestureRecognizer{
if([gestureRecognizer isMemberOfClass:[UIPinchGestureRecognizer class]])
{
effectiveScale = beginGestureScale * ((UIPinchGestureRecognizer *)gestureRecognizer).scale;
if (effectiveScale < 1.0)
effectiveScale = 1.0;
CGFloat maxScaleAndCropFactor = [[self.stillImageOutput connectionWithMediaType:AVMediaTypeVideo] videoMaxScaleAndCropFactor];
if (effectiveScale > maxScaleAndCropFactor)
effectiveScale = maxScaleAndCropFactor;
[CATransaction begin];
[CATransaction setAnimationDuration:.025];
[self.previewView.layer setAffineTransform:CGAffineTransformMakeScale(effectiveScale, effectiveScale)];
[CATransaction commit];
if ([[self videoDevice] lockForConfiguration:nil]) {
[[self videoDevice] setVideoZoomFactor:effectiveScale];
[[self videoDevice] unlockForConfiguration];
}}}}
** Note that the key method for persisting the zoom level for video device is [device setVideoZoomFactor:]
2- In the IBAction of the Record Button , add this code to capture the video ( recording ) then to save the recorded video in the a certain path with certain name
- (IBAction)recordButtonClicked:(id)sender {
dispatch_async([self sessionQueue], ^{
if (![[self movieFileOutput] isRecording])
{
[self setLockInterfaceRotation:YES];
if ([[UIDevice currentDevice] isMultitaskingSupported])
{
// Setup background task. This is needed because the captureOutput:didFinishRecordingToOutputFileAtURL: callback is not received until the app returns to the foreground unless you request background execution time. This also ensures that there will be time to write the file to the assets library when the app is backgrounded. To conclude this background execution, -endBackgroundTask is called in -recorder:recordingDidFinishToOutputFileURL:error: after the recorded file has been saved.
[self setBackgroundRecordingID:[[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:nil]];
}
// Update the orientation on the movie file output video connection before starting recording.
// Start recording to a temporary file.
NSString *outputFilePath = [NSTemporaryDirectory() stringByAppendingPathComponent:[#"movie" stringByAppendingPathExtension:#"mov"]];
[[self movieFileOutput] startRecordingToOutputFileURL:[NSURL fileURLWithPath:outputFilePath] recordingDelegate:self];
}
else
{
[[self movieFileOutput] stopRecording];
}
});
}
I hope that helps you

Add UIPinchGestureRecognizer object to your and handle callback like this:
- (void) zoomPinchGestureRecognizerAction: (UIPinchGestureRecognizer *) sender {
static CGFloat initialVideoZoomFactor = 0;
if (sender.state == UIGestureRecognizerStateBegan) {
initialVideoZoomFactor = _captureDevice.videoZoomFactor;
} else {
CGFloat scale = MIN(MAX(1, initialVideoZoomFactor * sender.scale), 4);
[CATransaction begin];
[CATransaction setAnimationDuration: 0.01];
_previewLayer.affineTransform = CGAffineTransformMakeScale(scale, scale);
[CATransaction commit];
if ([_captureDevice lockForConfiguration: nil] == YES) {
_captureDevice.videoZoomFactor = scale;
[_captureDevice unlockForConfiguration];
}
}
}

Related

How to Move the annotation over the route/overlay and rotate the annotation in the direction of movement?

I'm trying to move an annotation along a route as shown in fig.
I'm tried to move an annotation by finding the coordinates between source and destination by using MKGeodesicPolyline.But in this case the annotation move in a straight line as shown in fig.
The code for this movement is give below:-
-(void)toGetRoute:(CLPlacemark*)destinationCoord
{
MKDirectionsRequest *directionRequest=[MKDirectionsRequest new];
MKMapItem *source=[MKMapItem mapItemForCurrentLocation];
[directionRequest setSource:source];
CLLocationCoordinate2D destinationCoordinates= CLLocationCoordinate2DMake(destinationCoord.location.coordinate.latitude, destinationCoord.location.coordinate.longitude);
CLLocation *LAX = [[CLLocation alloc] initWithLatitude:37.332331
longitude:-122.031219];
CLLocation *JFK = [[CLLocation alloc] initWithLatitude:37.365080
longitude:-121.984600];
CLLocationCoordinate2D coordinates[2] =
{LAX.coordinate, JFK.coordinate};
// MKMapPoint points=MKMapPointForCoordinate(destinationCoordinates) ;
geodesic=[MKGeodesicPolyline polylineWithCoordinates:coordinates count:2];//polylineWithPoints:&points count:2];
NSLog(#"pointCount %lu", (unsigned long)geodesic.pointCount);
[self.mapView addOverlay:geodesic];
MKPlacemark *destinationPlacemark=[[MKPlacemark alloc]initWithCoordinate:destinationCoordinates addressDictionary:nil];
MKMapItem *destination=[[MKMapItem alloc]initWithPlacemark:destinationPlacemark];
[directionRequest setDestination:destination];
directionRequest.requestsAlternateRoutes=YES; // to show multiple route.
directionRequest.transportType=MKDirectionsTransportTypeAutomobile;
MKDirections *direction=[[MKDirections alloc]initWithRequest:directionRequest];
//calculate the actual route
[direction calculateDirectionsWithCompletionHandler:^(MKDirectionsResponse * _Nullable response, NSError * _Nullable error) {
if (error) {
NSLog(#"There was an error getting your directions");
return;
}
NSLog(#"no of routes %lu",response.routes.count);
// [self showMultipleRoute:response];
currentRoute=[response.routes firstObject];
[self plotRouteOnMap:currentRoute destinationCoordinate:destinationCoord];
for (MKRouteStep *step in currentRoute.steps)
{
NSLog(#"%#", step.instructions);
}
}];
}
here we update annotation:-
-(void)updatePlanePosition:(MKAnnotationView *)view
{
//this example updates the position in increments of 50...
planePositionIndex = planePositionIndex + 1;
if (planePositionIndex >= geodesic.pointCount)
{
//plane has reached end, stop moving
return;
}
MKMapPoint nextMapPoint = geodesic.points[planePositionIndex];
//convert MKMapPoint to CLLocationCoordinate2D...
CLLocationCoordinate2D nextCoord = MKCoordinateForMapPoint(nextMapPoint);
NSLog(#"nextCoord %f,%f",nextCoord.latitude,nextCoord.longitude);
//update the plane's coordinate...
[pntanotation setCoordinate:nextCoord];
// [UIView animateWithDuration:10.0f
// animations:^{
//
// [view.annotation setCoordinate:nextCoord];
// // [mapView setCenterCoordinate:CLLocationCoordinate2DMake(28.5, 77.00) animated:YES];
// }completion:^(BOOL finished) {
// NSLog(#"annotation animation completed");
// }];
//schedule the next update...
[self performSelector:#selector(updatePlanePosition:) withObject:nil afterDelay:0.3];
}
But I don't want to move annotation in a straight line. I want that it should move along the route and it should rotate in the direction of movement.
please help me.

Make rounded image with storyboards

I want to make rounded photo from Facebook, but image always scales.
So i have Storyboard with next parameters:
http://prntscr.com/5bpuqy
align center X, align center Y, width equals 72, height equals 72.
I understand, that problem may be in 72/72, but image mode in storyboard is "Aspect Fit"
I call my methods for downloading image by URL and then make it cornered with radius.
// call
[UIImage setRoundImageView:self.p_photo WithURL:[p_user fullURL] withCornerSize:37];
+ (void)setRoundImageView:(UIImageView *)imageView WithURL:(NSURL *)url withCornerSize:(CGFloat)corner
{
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
[[SDWebImageManager sharedManager] downloadImageWithURL:url
options:0
progress:^(NSInteger receivedSize, NSInteger expectedSize) {
} completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
if (image && finished)
{
[self setRoundImage:image forImageView:imageView withCornerSize:corner];
}
}];
});
}
+ (void)setRoundImage:(UIImage *)image forImageView:(UIImageView *)imageView withCornerSize:(CGFloat)corner
{
dispatch_async(dispatch_get_main_queue(), ^{
UIGraphicsBeginImageContextWithOptions(imageView.bounds.size, NO, [UIScreen mainScreen].scale);
[[UIBezierPath bezierPathWithRoundedRect:imageView.bounds
cornerRadius:corner] addClip];
[image drawInRect:imageView.bounds];
imageView.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
});
}
Your code is way more complex than it needs to be. You are manually drawing the image into the image view and that is causing the problem. Try this instead:
+ (void)setRoundImageView:(UIImageView *)imageView WithURL:(NSURL *)url
{
// you don't need to wrap this in a dispatch queue, SDWebImageManager takes care of that for you.
[[SDWebImageManager sharedManager] downloadImageWithURL:url options:0 progress:^(NSInteger receivedSize, NSInteger expectedSize) {
} completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
if (image && finished) {
[self setRoundImage:image forImageView:imageView];
}
}];
}
+ (void)setRoundImage:(UIImage *)image forImageView:(UIImageView *)imageView
{
// you don't need to wrap this in a dispatch queue, it will be called on the main thread.
// you don't need to manually draw the image into the image view. Just add the image to the image view and let it do its thing.
imageView.layer.cornerRadius = CGRectGetHeight(imageView.bounds) / 2;
imageView.layer.masksToBounds = YES;
[imageView setImage:image];
}
And make sure the image view is set to "Aspect Fill" mode in the storyboard.

How to make a full screen landscape camera without any buttons?

When the app launches I just want to make it display a camera view in full screen, without any on screen buttons, just the actual part which the camera is seeing.
You wont want to use the camera then. There are multiple ways to do this, the quickest is through a AVCaptureVideoPreviewLayer
Check out this answer: Get Camera Preview to AVCaptureVideoPreviewLayer
- (void)initCapture
{
AVCaptureDevice *inputDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
AVCaptureDeviceInput *captureInput = [AVCaptureDeviceInput deviceInputWithDevice:inputDevice error:nil];
if (!captureInput) {
return;
}
AVCaptureVideoDataOutput *captureOutput = [[AVCaptureVideoDataOutput alloc] init];
/* captureOutput:didOutputSampleBuffer:fromConnection delegate method !*/
[captureOutput setSampleBufferDelegate:self queue:dispatch_get_main_queue()];
NSString* key = (NSString*)kCVPixelBufferPixelFormatTypeKey;
NSNumber* value = [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA];
NSDictionary* videoSettings = [NSDictionary dictionaryWithObject:value forKey:key];
[captureOutput setVideoSettings:videoSettings];
self.captureSession = [[AVCaptureSession alloc] init];
NSString* preset = 0;
if (!preset) {
preset = AVCaptureSessionPresetMedium;
}
self.captureSession.sessionPreset = preset;
if ([self.captureSession canAddInput:captureInput]) {
[self.captureSession addInput:captureInput];
}
if ([self.captureSession canAddOutput:captureOutput]) {
[self.captureSession addOutput:captureOutput];
}
//handle prevLayer
if (!self.captureVideoPreviewLayer) {
self.captureVideoPreviewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.captureSession];
}
//if you want to adjust the previewlayer frame, here!
self.captureVideoPreviewLayer.frame = self.view.bounds;
self.captureVideoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
[self.view.layer addSublayer: self.captureVideoPreviewLayer];
[self.captureSession startRunning];
}
Also see:
Live camera in UIImageView
https://developer.apple.com/library/ios/documentation/AVFoundation/Reference/AVCaptureVideoPreviewLayer_Class/Reference/Reference.html

Issue in previewing the video using AVFoundation and MPMovieController at a time in iphone sdk

I am Using AVFoundation's AVCaptureSession to capture the video and I am using the MPMoviePlayerController to play the streamed url(video) from server. When I am capturing only video with AVCaptureSession there is no problem. But When I tried to play the streamed url(with MPMoviePlayerController) along with capturing of video with AVCaptureSession at a time the problem occurs as the capturing from AVCaptureSession stops.
This is what I had done:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication ]delegate];
if([appDelegate isIpad] == YES)
controlsView = [[UIView alloc] initWithFrame:CGRectMake(self.view.bounds.origin.x+200, self.view.bounds.origin.y+250, self.view.bounds.size.width, self.view.bounds.size.height)];
else
controlsView = [[UIView alloc] initWithFrame:self.view.bounds];
controlsView.backgroundColor = [UIColor blackColor];
[self.view addSubview:controlsView];
[self.view sendSubviewToBack:controlsView];
//settingsBtn = [[UIButton alloc]initWithFrame:CGRectMake(10,400, 50, 50)];
settingsBtn = [[UIButton alloc]initWithFrame:CGRectMake(10,400, 50, 50)];
[settingsBtn setImage:[UIImage imageNamed:#"settings.png"] forState:UIControlStateNormal];
[settingsBtn addTarget:self action:#selector(settingsAction) forControlEvents:UIControlEventTouchUpInside];
[controlsView addSubview:settingsBtn];
callButton = [[UIButton alloc]initWithFrame:CGRectMake(260,400, 50, 50)];
if(isCallButtonClicked ==NO)
[callButton setImage:[UIImage imageNamed:#"call.png"] forState:UIControlStateNormal];
else
[callButton setImage:[UIImage imageNamed:#"callEnd.png"] forState:UIControlStateNormal];
[callButton addTarget:self action:#selector(callAction) forControlEvents:UIControlEventTouchUpInside];
[controlsView addSubview:callButton];
statusLabel = [[UILabel alloc]initWithFrame:CGRectMake(120, 20, 150, 40)];
statusLabel.textColor = [UIColor whiteColor];
statusLabel.backgroundColor = [UIColor clearColor];
statusLabel.textAlignment = UITextAlignmentLeft;
statusLabel.font = [UIFont boldSystemFontOfSize:20];
dot1 = [[UIView alloc] initWithFrame:CGRectMake(75, 20, 7, 7)];
dot1.layer.cornerRadius = 5;
dot1.backgroundColor = [UIColor whiteColor];
[statusLabel addSubview:dot1];
dot2 = [[UIView alloc] initWithFrame:CGRectMake(84, 20, 7, 7)];
dot2.layer.cornerRadius = 5;
dot2.backgroundColor = [UIColor whiteColor];
[statusLabel addSubview:dot2];
dot3 = [[UIView alloc] initWithFrame:CGRectMake(93, 20, 7, 7)];
dot3.layer.cornerRadius = 5;
dot3.backgroundColor = [UIColor whiteColor];
[statusLabel addSubview:dot3];
downStreamView = [[UIView alloc]initWithFrame:CGRectMake(controlsView.bounds.origin.x, controlsView.bounds.origin.y, controlsView.bounds.size.width, controlsView.bounds.size.height - 70)];
[[controlsView layer] addSublayer:downStreamView.layer];
downStreamView.layer.backgroundColor = [UIColor greenColor].CGColor;
AVCaptureSession *captureSession = [[AVCaptureSession alloc]init];
NSError *error;
/* getting the device input */
AVCaptureDeviceInput *videoInput = [AVCaptureDeviceInput deviceInputWithDevice:[self frontFacingCamera] error:&error];
if(error)
{
NSLog(#"%#",#"Could not create video input");
}
[captureSession addInput:videoInput];
AVCaptureDeviceInput *audioInput = [AVCaptureDeviceInput deviceInputWithDevice:[self audioDevice] error:&error];
[captureSession addInput:audioInput];
audioOutput = [[AVCaptureAudioDataOutput alloc]init];
[captureSession addOutput:audioOutput];
previewLayer = [[AVCaptureVideoPreviewLayer alloc]initWithSession:captureSession];
[previewLayer setFrame:CGRectMake(controlsView.bounds.origin.x, controlsView.bounds.origin.y, controlsView.bounds.size.width, controlsView.bounds.size.height - 70)];
[previewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
[[controlsView layer] addSublayer:previewLayer];
[captureSession startRunning];
}
//make call Action
-(void)makeCallAction
{
if(isCallButtonClicked == NO)
{
statusLabel.text = #"Dialling";
[controlsView addSubview:statusLabel];
if(!isAnimationStarted)
[self animate];
[callButton setImage:[UIImage imageNamed:#"callEnd.png"] forState:UIControlStateNormal];
[UIView animateWithDuration:2.0
animations:^{
CGRect frame = CGRectMake(downStreamView.layer.bounds.origin.x, downStreamView.layer.bounds.size.height-100, 100, 100);
previewLayer.frame = frame;
[downStreamView.layer addSublayer:previewLayer];
}
completion:^(BOOL finished){
//Do nothing
}];
isCallButtonClicked = YES;
}
else if(isCallButtonClicked == YES)
{
[statusLabel removeFromSuperview];
[callButton setImage:[UIImage imageNamed:#"call.png"] forState:UIControlStateNormal];
[UIView animateWithDuration:2.0
animations:^{
[previewLayer setFrame:CGRectMake(controlsView.bounds.origin.x, controlsView.bounds.origin.y, controlsView.bounds.size.width, controlsView.bounds.size.height - 70)];
[[controlsView layer] addSublayer:previewLayer];
}
completion:^(BOOL finished){
//Do nothing
}];
isCallButtonClicked = NO;
}
}
//Settings Action
-(void)settingsAction
{
NSString *nibName = nil;
if ([[[UIDevice currentDevice] model] isEqualToString:#"iPhone"] || [[[UIDevice currentDevice] model] isEqualToString:#"iPhone Simulator"]) {
nibName = #"SettingsViewController";
}
else {
nibName = #"SettingsViewController_iPad";
}
SettingsViewController *settingsController = [[SettingsViewController alloc]initWithNibName:nibName bundle:nil];
[self.navigationController presentModalViewController:settingsController animated:YES];
}
-(void)callAction
{
NSURL *theMovieURL = [NSURL URLWithString:#"someURL.m3u8"];
if (theMovieURL)
{
if ([theMovieURL scheme]) // sanity check on the URL
{
/* Play the movie with the specified URL. */
[self playStreamingURL:theMovieURL];
}
}
[self makeCallAction];
}
-(void)playStreamingURL:(NSURL *)aUrlStr
{
MPMovieSourceType movieSourceType = MPMovieSourceTypeUnknown;
/* If we have a streaming url then specify the movie source type. */
if ([[aUrlStr pathExtension] compare:#"m3u8" options:NSCaseInsensitiveSearch] == NSOrderedSame)
{
movieSourceType = MPMovieSourceTypeStreaming;
}
[self createAndPlayMovieForURL:aUrlStr sourceType:movieSourceType];
}
-(void)createAndPlayMovieForURL:(NSURL *)movieURL sourceType:(MPMovieSourceType)sourceType
{
[self createAndConfigurePlayerWithURL:movieURL sourceType:sourceType];
/* making the player to be visible in full screen mode */
//if(!self.moviePlayerController.fullscreen)
// self.moviePlayerController.fullscreen = YES;
/* disabling the controls of the movie player */
self.moviePlayerController.controlStyle = MPMovieControlStyleNone;
/* Play the movie! */
[[self moviePlayerController] play];
}
-(void)createAndConfigurePlayerWithURL:(NSURL *)movieURL sourceType:(MPMovieSourceType)sourceType
{
[controlsView addSubview:downStreamView];
/* Create a new movie player object. */
MPMoviePlayerController *player = [[MPMoviePlayerController alloc] initWithContentURL:movieURL];
if (player)
{
/* Save the movie object. */
[self setMoviePlayerController:player];
player.contentURL = MPMovieControlStyleNone;
//if(!player.fullscreen)
// player.fullscreen = YES;
/* Register the current object as an observer for the movie
notifications. */
// [self installMovieNotificationObservers];
/* Specify the URL that points to the movie file. */
[player setContentURL:movieURL];
/* If you specify the movie type before playing the movie it can result
in faster load times. */
[player setMovieSourceType:sourceType];
/* Apply the user movie preference settings to the movie player object. */
//[self applyUserSettingsToMoviePlayer];
/* Add a background view as a subview to hide our other view controls
underneath during movie playback. */
//CGRect viewInsetRect = CGRectInset ([self.view bounds],
// kMovieViewOffsetX,
//kMovieViewOffsetY );
/* Inset the movie frame in the parent view frame. */
[[player view] setFrame:downStreamView.bounds];
[player view].backgroundColor = [UIColor redColor];
/* To present a movie in your application, incorporate the view contained
in a movie player’s view property into your application’s view hierarchy.
Be sure to size the frame correctly. */
[downStreamView.layer addSublayer: [player view].layer];
}
}
-(void)installMovieNotificationObservers
{
MPMoviePlayerController *player = [self moviePlayerController];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(loadStateDidChange:)
name:MPMoviePlayerLoadStateDidChangeNotification
object:player];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayBackDidFinish:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:player];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(mediaIsPreparedToPlayDidChange:)
name:MPMediaPlaybackIsPreparedToPlayDidChangeNotification
object:player];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayBackStateDidChange:)
name:MPMoviePlayerPlaybackStateDidChangeNotification
object:player];
}
/* Notification called when the movie finished playing. */
- (void) moviePlayBackDidFinish:(NSNotification*)notification
{
NSNumber *reason = [[notification userInfo] objectForKey:MPMoviePlayerPlaybackDidFinishReasonUserInfoKey];
switch ([reason integerValue])
{
/* The end of the movie was reached. */
case MPMovieFinishReasonPlaybackEnded:
/*
Add your code here to handle MPMovieFinishReasonPlaybackEnded.
*/
break;
/* An error was encountered during playback. */
case MPMovieFinishReasonPlaybackError:
NSLog(#"An error was encountered during playback");
[self performSelectorOnMainThread:#selector(displayError:) withObject:[[notification userInfo] objectForKey:#"error"] waitUntilDone:NO];
[self removeMovieViewFromViewHierarchy];
break;
/* The user stopped playback. */
case MPMovieFinishReasonUserExited:
[self removeMovieViewFromViewHierarchy];
break;
default:
break;
}
}
/* Remove the movie view from the view hierarchy. */
-(void)removeMovieViewFromViewHierarchy
{
MPMoviePlayerController *player = [self moviePlayerController];
[player.view removeFromSuperview];
}
- (void)animate {
isAnimationStarted = YES;
//First Animation
[UIView animateWithDuration:0.5 animations:^{
dot1.alpha = 1;
dot2.alpha = 0.5;
dot3.alpha = 0.5;
} completion:^(BOOL finished) {
//2nd Animation
[UIView animateWithDuration:0.5 animations:^{
dot1.alpha = 0.5;
dot2.alpha = 1;
dot3.alpha = 0.5;
} completion:^(BOOL finished) {
//3rd Animation
[UIView animateWithDuration:0.5 animations:^{
dot1.alpha = 0.5;
dot2.alpha = 0.5;
dot3.alpha = 1;
} completion:^(BOOL finished) {
[self performSelector:#selector(animate)];
}];
}];
}];
}
// Find a camera with the specificed AVCaptureDevicePosition, returning nil if one is not found
- (AVCaptureDevice *) cameraWithPosition:(AVCaptureDevicePosition) position
{
NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
for (AVCaptureDevice *device in devices) {
if ([device position] == position) {
return device;
}
}
return nil;
}
// Find a front facing camera, returning nil if one is not found
- (AVCaptureDevice *) frontFacingCamera
{
return [self cameraWithPosition:AVCaptureDevicePositionFront];
}
// Find a back facing camera, returning nil if one is not found
- (AVCaptureDevice *) backFacingCamera
{
return [self cameraWithPosition:AVCaptureDevicePositionBack];
}
- (AVCaptureDevice *) audioDevice
{
NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeAudio];
if ([devices count] > 0) {
return [devices objectAtIndex:0];
}
return nil;
}
-(void)audioData:(id)info
{
NSArray *connections = audioOutput.connections;
AVCaptureConnection *connection = [connections objectAtIndex:0];
NSArray *audioChannels = connection.audioChannels;
AVCaptureAudioChannel *audioChannel = [audioChannels objectAtIndex:0];
//[label setText:[NSString stringWithFormat:#"%f", audioChannel.averagePowerLevel]];
}
Guy's Please help me how to resolve this issue :(
Regards

HUD Spinner does not appear when saving image to library

Hi I am implementing a 'save image to library' feature as seen in the code snippet below. Basically, the photo saving is triggered when a user touches an image on the page.
TouchImageView *tiv = [[TouchImageView alloc]initWithFrame:blockFrame];
[tiv setCompletionHandler:^(NSString *imageUrl){
//Spinner should start after user clicks on an image
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.navigationController.view animated:YES];
hud.labelText = #"Saving photo to library";
//trigger method to save image to library
[self saveImageToLibrary];
}];
-(void) saveImageToLibrary
{
//convert url to uiimage
UIImage *selectedImage = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:imageURL]]];
//Save image to album
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
// Request to save the image to camera roll
[library writeImageToSavedPhotosAlbum:[selectedImage CGImage] orientation:(ALAssetOrientation)[selectedImage imageOrientation] completionBlock:^(NSURL *assetURL, NSError *error){
[MBProgressHUD hideHUDForView:self.navigationController.view animated:YES];
if (error) {
NSLog(#"error");
} else {
NSLog(#"url %#", assetURL);
//Trigger get photo from library function
self.imgPicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentModalViewController:self.imgPicker animated:YES];
}
}];
[library release];
}
The issue is that the HUD spinner does not appear (after a lag time of 3-4 seconds), my suspicion is that the 'writeImageToSavedPhotosAlbum:' is synchronous and locked the process from displaying the HUD spinner. Is this right? How do I resolve the lag in spinner display?
Yes, that is correct. Replace the call
[self saveImageToLibrary];
by
[self performSelector:#selector(saveImageToLibrary) withObject:nil afterDelay:0];
so that the HUD gets a chance to show itself before you save.