UIImagePickerController won't record a video - objective-c

I want to record a video with UIImagePickerController. My Problem is that the method [imagePickerController startVideoCapture]; always returns 0. I am testing the application with an iPhone 4S running iOS 5.1. Could somebody please help me with this:
- (IBAction)playButtonPushed:(id)sender
{
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
{
UIView *videoView = self.videoViewController.view;
UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] >init];
imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
imagePickerController.mediaTypes = [[NSArray alloc] initWithObjects: (NSString >*)kUTTypeMovie, nil];
imagePickerController.showsCameraControls = NO;
imagePickerController.toolbarHidden = NO;
imagePickerController.wantsFullScreenLayout = YES;
imagePickerController.allowsEditing = YES;
imagePickerController.videoQuality = UIImagePickerControllerQualityTypeMedium;
imagePickerController.videoMaximumDuration = 30;
[imagePickerController startVideoCapture];
imagePickerController.cameraViewTransform = > CGAffineTransformScale(self.imagePickerViewController.cameraViewTransform, CAMERA_TRANSFORM, CAMERA_TRANSFORM);
imagePickerController.delegate = self;
[self.imagePickerViewController setCameraOverlayView:videoView];
NSLog(#"%s videoCapture: %d", __PRETTY_FUNCTION__, [imagePickerController > startVideoCapture]
);
[self presentModalViewController:imagePickerViewController animated:YES];
}
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
NSLog(#"didFinishPickingMediaWithInfo");
NSURL *videoURL = [info objectForKey:UIImagePickerControllerMediaURL];
NSData *videoData = [NSData dataWithContentsOfURL:videoURL];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
NSLog(#"Cancel");
}

I had the same problem and Apple's documentation didn't help. That's because they missed to mention that startVideoCapture() can return false if you haven't set the capture mode to .video like this:
picker.cameraCaptureMode = .video
This worked for me and I'm able to capture videos now.

If im not mistaken, the "startVideoCapture" method is a bool
Taken straight from apple documentation:
startVideoCapture
Starts video capture using the camera specified by the UIImagePickerControllerCameraDevice property.
- (BOOL)startVideoCapture
Return Value
YES on success or NO on failure. This method may return a value of NO for various reasons, among them the following:
Movie capture is already in progress
The device does not support movie capture
The device is out of disk space
Discussion
Use this method in conjunction with a custom overlay view to initiate the programmatic capture of a movie. You can take more than one movie without leaving the interface, but to do so requires you to hide the default image picker controls.
Calling this method while a movie is being captured has no effect. You must call the stopVideoCapture method, and then wait until the associated delegate object receives an imagePickerController:didFinishPickingMediaWithInfo: message, before you can capture another movie.
Calling this method when the source type of the image picker is set to a value other than UIImagePickerControllerSourceTypeCamera results in the throwing of an NSInvalidArgumentException exception.
If you require additional options or more control over movie capture, use the movie capture methods in the AV Foundation framework. Refer to AV Foundation Framework Reference.
Availability
Available in iOS 4.0 and later.
Declared In
UIImagePickerController.h
stopVideoCapture
Stops video capture.
- (void)stopVideoCapture
Discussion
After you call this method to stop video capture, the system calls the image picker delegate’s imagePickerController:didFinishPickingMediaWithInfo: method.
Availability
Available in iOS 4.0 and later.
Declared In
UIImagePickerController.h

Think you need to call the startVideoCapture method after calling presentModalViewController:animated: and not before.
You probably also need a short delay (<1s?) after the UIImagePickerController has been presented on-screen and the animation has stopped, then call startVideoCapture, otherwise there are times where it will not start recording.

I had exactly the same problem. AndyV has it right, the recording won't start until the picker has been presented. I spent a lot of time trying to introduce a delay with sleep, but the simplest solution is to start a timer after displaying the picker using
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval: 1.0 target:self selector:#selector(startRecording) userInfo:nil repeats: NO];
Then ..
- (void)startRecording
{
BOOL result = [picker startVideoCapture];
}

Related

iOS:View controller crashes when trying to use camera in an application.

I have a button where when the user presses it, he is navigated to camera to take a pic.
When he takes the pic, he presses done and gets back to the controller. But when that happens the navigation bar gets up in the screen, gets below the battery/signal bar that the telephone has. The weird thing is that this happens on 4/4s but not on 3gs
It is rather tough to answer the question without knowing a bit more details, but here's some code I use to bring up the camera, take the picture, then close the camera successfully. The method can be called by using one line of code: [self takePhoto];
- (void) takePhoto {
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
//Clear out the UI first
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
//picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary; -> use this if you want them to select from the library
[self presentViewController:picker animated:YES completion:nil];
} else {
//Device does not support a camera, show a message if desired
}
}
Then you need a delegate for it all so the program knows what to do when an image is taken or selected and how to close, that's what this code is:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
self.workingImage = nil;
//I grab the image and store globally, but first I manually scale and rotate it if necessary
self.workingImage = [self scaleAndRotateImage:[info objectForKey:UIImagePickerControllerOriginalImage]];
//I display the image in my UI view, so this chunk of code will size it properly
CGRect bound;
bound.origin = CGPointZero;
bound.size = img.size;
imageView.bounds = bound;
//Set the UI image view and dismiss the controller
[imageView setImage:self.workingImage];
[picker dismissModalViewControllerAnimated:YES];
}
Obviously, make sure your controller .h implements the delegate properly like so:
#interface ViewController : UIViewController<UIImagePickerControllerDelegate> { ... }
Hope this helps?

Load an UIActivityIndicator over a UIImagePickerController in iOS

I am currently writing an iOS app and do not like the speed at which the UIImagePickerController disappears.
I call [self dismissModalViewControllerAnimated:YES]; the instant I am inside of - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info; And yet the imagePicker takes several moments to disappear, long enough on some photos that the app appears frozen to the user.
One solution I thought of was to just throw up a UIActivityIndicator infront of the UIImagePickerController but I have not figured out a way to accomplish this.
Thank you!
Edit: Any tips on how to save UIImages faster would help too I believe. Such as a way to do it asynchronously.
There is a great tutorial on doing this with grand central dispatch and code blocks by Ray Wenderlich :
http://www.raywenderlich.com/1888/how-to-create-a-simple-iphone-app-tutorial-part-33
You can also do this with a job queue and performSelector:onThread:withObject:waitUntilDone: if blocks are scary to you.
Basically, the idea is to do the least amount of real work on the main thread, because that's where the UI is drawn. Below is RW's solution, with the status part commented out. That's where you put an activity indicator.
- (IBAction)addPictureTapped:(id)sender {
if (self.picker == nil) {
// 1) Show status
//[SVProgressHUD showWithStatus:#"Loading picker..."];
// 2) Get a concurrent queue form the system
dispatch_queue_t concurrentQueue =
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// 3) Load picker in background
dispatch_async(concurrentQueue, ^{
self.picker = [[UIImagePickerController alloc] init];
self.picker.delegate = self;
self.picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
self.picker.allowsEditing = NO;
// 4) Present picker in main thread
dispatch_async(dispatch_get_main_queue(), ^{
[self.navigationController presentModalViewController:picker animated:YES];
[SVProgressHUD dismiss];
});
});
} else {
[self.navigationController presentModalViewController:picker animated:YES];
}
}

UIImagePickerController delegate is not calling

Iam using the following code for taking the picture automatically from IPAD front camera:
UIImagePickerController *imgPkr = [[UIImagePickerController alloc] init];
imgPkr.sourceType = UIImagePickerControllerSourceTypeCamera;
imgPkr.delegate = self;
imgPkr.cameraDevice=UIImagePickerControllerCameraDeviceFront;
[self presentModalViewController:imgPkr animated:YES];
imgPkr.showsCameraControls = NO;
[imgPkr takePicture];
But this code Dont take any picture and dont call the delegate:
-(void)imagePickerController:(UIImagePickerController*)picker
didFinishPickingMediaWithInfo:(NSDictionary*)info
Any idea what is wrong with the code
My first guess is that [imgPkr takePicture]; is being called before the picker is done being presented. Try it like this:
UIImagePickerController *imgPkr = [[UIImagePickerController alloc] init];
imgPkr.sourceType = UIImagePickerControllerSourceTypeCamera;
imgPkr.delegate = self;
imgPkr.cameraDevice=UIImagePickerControllerCameraDeviceFront;
[self presentModalViewController:imgPkr animated:YES];
imgPkr.showsCameraControls = NO;
[self performSelector:#selector(takePicture) withObject:self afterDelay:1.0];
OR
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(takePicture)
name:AVCaptureSessionDidStartRunningNotification
object:nil];
&
- (void)takePicture
{
[imgPkr takePicture];
}
I bet that you get a message in your logs saying that
UIImagePickerController: ignoring request to take picture; camera is
not yet ready.
This is a common problem because the underlying capture session needs some time to start, so you just have to be sure that the camera is ready to take a picture and then call takePicture method. Now, a way to get notified is explained in detail in my answer here: How to know if iPhone camera is ready to take picture?
Note though that this method will work on iOS5+ (there is a bug in older versions that prevents the system notifications for this event, contrary to what is described in the documentation). I hope that this helps.
another way to wait for camera ready until take picture is completion block ->
[self presentViewController:imagePicker animated:YES
completion:^ {
[imagePicker takePicture];
}];
thank you 'GrandSteph' at
iOS taking photo programmatically

UIImagePickerController - tapping the Album TableView or Selecting Album causes table to go blank? iOS5

I'm trying to reproduce a Similar Media Picker that is like the one in Pages. Within a UIPopoverController There is a UISegmentedControl that selects different media Types. One of the SegmentedControls I have is Labeled Images. I want to be able to select that Segment and have the view below present the ImagePicker.
I'm Close. I have a few issues. When presenting the VC, I get:
I get the Following in the Debugger:
UIStatusBarStyleBlackTranslucent is not available on this device. Not sure where that is coming from. I've tried with and without:
imagePicker.modalInPopover = YES;
imagePicker.modalPresentationStyle = UIModalPresentationCurrentContext;
Though I still cannot get it to work Right. It Presents just fine. I see the UISegmentedControl I see my other Media Pages, I click the Image segment and I see the ImagePicker, Title is 'Photos' Has a Cancel Button I need to get rid of, and shows the two Albums I have on the device.
If I tap anywhere in the TableView (on an album or not), the two Albums go away. The NavBar and Cancel button are still there, though no Albums anymore. Tapping an Album Highlights the Row, though does not show the Images within the Album.
The other odd part of my code is that the Delegate for the Image Picker is the VC that Presented the UIPopoverController. Not sure if that plays into it. When I do hit the Cancel Button, I get:
-[PLUILibraryViewController performSelector:withObject:withObject:]: message sent to deallocated instance
Here is my Code to present the Picker.
- (void) setupImagePicker {
IoScreenEditorViewController * ioScreenEditorViewController = (IoScreenEditorViewController *)[UIAppDelegate.ioMainViewController currentViewController];
ioScreenEditorViewController.elementSelectedFromList = [elementsForPage objectAtIndex:0];
// Show an image picker to allow the user to choose a new photo.
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate = ioScreenEditorViewController;
imagePicker.allowsEditing = NO;
NSArray * ourMediaTypes = [[NSArray alloc] initWithObjects: (NSString *) kUTTypeImage, nil];
[imagePicker setMediaTypes: ourMediaTypes];
[ourMediaTypes release];
if ([UIImagePickerController isSourceTypeAvailable: UIImagePickerControllerSourceTypeCamera]) {
// imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
} else {
imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
}
[imagePicker.view setFrame:CGRectMake(0,0, 340, 500)]; // just for testing
//imagePicker.modalInPopover = YES;
//imagePicker.modalPresentationStyle = UIModalPresentationCurrentContext;
[self.view addSubview:imagePicker.view];
[imagePicker release];
}
I changed the class type that the Picker was being called from to a UIViewController and then altered the presentation code to look like this:
imagePicker.modalInPopover = YES;
imagePicker.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentViewController:imagePicker animated:NO completion:^{ }];
I still get the Cancel Button, though the Image Picker does seem to be working like it should.
Although I was also as of yet unable to hide the Cancel button of the picker, I would suggest you revise how you are presenting it.
As an effort to get help from the community of iOS developers about this, I've made a sample project, please go and download it. In the project you can see that I am using view controller containment in order to get the picker on screen.
This may perhaps be a better way for you do do this too?
https://bitbucket.org/danielphillips/image-picker-demo

How do I use UIImagePickerController just to display the camera and not take a picture?

I'd like to know how to open the camera inside of a pre-defined frame (not the entire screen). When the view loads, I have a box, and inside it, I want to display what the camera sees. I don't want to snap a picture, just basically use the camera as a viewfinder. I have searched this site and have not yet found what I'm looking for. Please help.
Thanks!
Thomas
Update 1:
Here is what I have tried so far.
1.) I added UIImageView to my xib.
2.) Connect the following outlet to the UIImageView in IB
IBOutlet UIImageView *cameraWindow;
3.) I put the following code in viewWillAppear
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentModalViewController:picker animated:YES];
NSLog(#"viewWillAppear ran");
}
But this method does not run, as evident by the absence of NSLog statement from my console. Please help!
Thanks,
Thomas
Update 2:
OK I got it to run by putting the code in viewDidLoad but my camera still doesn't show up...any suggestions? Anyone....? I've been reading the UIImagePickerController class reference, but am kinda unsure how to make sense of it. I'm still learning iPhone, so it's a bit of a struggle. Please help!
- (void)viewDidLoad
{
[super viewDidLoad];
// Create a bool variable "camera" and call isSourceTypeAvailable to see if camera exists on device
BOOL camera = [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera];
// If there is a camera, then display the world throught the viewfinder
if(camera)
{
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
// Since I'm not actually taking a picture, is a delegate function necessary?
picker.delegate = self;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentModalViewController:picker animated:YES];
NSLog(#"Camera is available");
}
// Otherwise, do nothing.
else
NSLog(#"No camera available");
}
Thanks!
Thomas
Update 3:
A-HA! Found this on the Apple Class Reference.
Discussion
The delegate receives notifications
when the user picks an image or movie,
or exits the picker interface. The
delegate also decides when to dismiss
the picker interface, so you must
provide a delegate to use a picker. If
this property is nil, the picker is
dismissed immediately if you try to
show it.
Gonna play around with the delegate now. Then I'm going to read on wtf a delegate is. Backwards? Whatever :-p
Update 4:
The two delegate functions for the class are
– imagePickerController:didFinishPickingMediaWithInfo:
– imagePickerControllerDidCancel:
and since I don't actually want to pick an image or give the user the option to cancel, I am just defining the methods. They should never run though....I think.
add
[picker
dismissModelViewControllerAnimated:YES];
to delegate method bodies.
It will dismiss the view.