I am writing a simple video uploader application on iPhone 3GS where I first direct the user to photos album, and then select the video to share or upload. I am using the UIImagePickerController in the following way:
videoPickerCtrl = [[UIImagePickerController alloc] init];
videoPickerCtrl.delegate = self;
videoPickerCtrl.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
videoPickerCtrl.mediaTypes = [UIImagePickerController availableMediaTypesForSourceType:videoPickerCtrl.sourceType];
videoPickerCtrl.allowsImageEditing = NO;
videoPickerCtrl.mediaTypes = [NSArray arrayWithObject:(NSString *)kUTTypeMovie];
[window addSubview:videoPickerCtrl.view];
But I can see that once the controller is invoked, there is a disturbing video trimming interface that is presented. Once I press "choose", the video is always trimmed no matter whether I touch the trimming controls or not. Is there any way to get around this trimming interface and directly get the path of the video file ?
You should set allowsEditing = NO; instead of allowsImageEditing = NO; (which has been deprecated in 3.1). Then, the trimming interface should not appear unless the selected movie is longer than 10 minutes (from the docs: "Maximum movie duration is 10 minutes. If a user picks a movie that is longer in duration than 10 minutes, they are forced to trim it before saving it.").
Interesting problem. This is just for information should anyone else be looking at this. On iPad OS 3.2 I have found some problems retrieving video, although the picker works and I can select video from albums and not just from the camera roll.
Here's my working code frag
The call
NSArray *mediaTypesAllowed = [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypePhotoLibrary];
[picker setMediaTypes:mediaTypesAllowed];
picker.delegate = self;
picker.allowsEditing = NO;
picker.wantsFullScreenLayout = YES;
if(!IsEmpty(self.editBackgroundPopover)){
[self.editBackgroundPopover setContentViewController:picker animated:YES];
}
And here is the delegate method
imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
[self.editBackgroundPopover dismissPopoverAnimated:true];
NSString* mediaType = [info objectForKey:UIImagePickerControllerMediaType];
//not production code, do not use hard coded string in real app
if ( [ mediaType isEqualToString:#"public.image" ]) {
NSLog(#"Picked a photo");
}
//not production code, do not use hard coded string in real app
else if ( [ mediaType isEqualToString:#"public.movie" ]){
NSLog(#"Picked a movie at URL %#", [info objectForKey:UIImagePickerControllerMediaURL]);
NSURL *url = [info objectForKey:UIImagePickerControllerMediaURL];
NSLog(#"> %#", [url absoluteString]);
}
[[picker self] dismissModalViewControllerAnimated:YES];
}
However the video URL which I retrieve from the picker has the form
file:/localhost/private/var/mobile/Applications/C6FAC491-D27D-45A6-B805-951727ED2CEC/tmp/-Tmp-/trim.KOzqps.MOV
So it looks to me that the Video might be being processed through the trimming code even if I'm selecting the video as a whole. Note also that the movie, originally of type m4v when I loaded it through iTunes is of type MOV, which is of course unplayable on the device! I did try playing the URL but I received an alert saying "This kind of movie can't be played"
I don't quite understand what Apple is playing at here, the API appears not to really be usable as a way of loading and playing video from the photo library.
Hopefully IOS 4 will be more forthcoming, but for my iPad app, that's still months away.
Ok so I got it working long back after carefully looking at SDK docs. I am able to get videos from Camera Roll directory on my 3GS. But I can not find any way in which UIImagePickerController can choose video from directories other than Camera Roll(for instance, device's Photo Library where the user syncs videos through iTunes). Is there any standard way in SDK to do that ?
Related
I am using UIImagePicker for selecting video from library and trying to use the video in my application.For this I am using code like this
picker = [[UIImagePickerController alloc] init];
picker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
picker.delegate = self;
picker.mediaTypes=[NSArray arrayWithObject:(NSString*)kUTTypeMovie];
[self presentModalViewController:picker animated:YES];
Now the problem is that when any video is selected it shows compressing video message alongwith a progress bar.Meanwhile If I send my app in background I want to cancel this compression and dismismodalviewController so that corrupted compression does not occur.Is there any way to avoid this compression or to handle this so that result is either in success or in failure.Setting videoQuality is not solving the problem.
In my case, the URL coming from UIImagePickerControllerMediaType was nil. The solution was getting the video URL from UIImagePickerControllerReferenceURL:
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
NSURL* url = [info objectForKey:UIImagePickerControllerReferenceURL];
//... read video with ALAssetsLibrary
}
Further info on how to read the video can be found here: How to save video from assets url
I am going to ask that one question that perhaps has been already asked a million times.
I am making an app for iPad and want to give users the ability to multi-select images from their photo-library. I already have a working code for user to select one image at a time. (not what I need)
I have already downloaded and looked into ELC image picker sample code but that code is not compatible with iOS 5 or Xcode 4. i.e. it has ARC and compile problems left and right, its using release and dealloc all over the place.
I am just frustrated that apple hasn't already created a built in-api for us developers for this most commonly requested functionality in most of our iPhone/ipad apps. (not one but multi-select pics)
Is there any other sample code available? Trust me, I have been googling for a while.
Ok, I have this figured out. The problem with Assets Library is that it gives you all the GEO data of the image. What that means for your users using your app is that they will get a prompt saying that your app is trying to access their location. Infact all you are trying to do is let them choose multiple images from their photo-album. Most users will be turned off thinking its a piracy issue. The best approach is to use apples api of imagePickerController. I know it lets you choose one pic at a time but if you add the following code, it will let you choose multiple pictures.
The way I am doing is let the users keep selecting pictures they want, keep saving those files in the app documents directory, till they hit the done button. See here my sample code and hopefully it will save you the pain of going through Assets Library
-(IBAction)selectExitingPicture
{
//Specially for fing iPAD
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate = self;
imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
imagePicker.mediaTypes = [NSArray arrayWithObject:(NSString *)kUTTypeImage];
popoverController = [[UIPopoverController alloc] initWithContentViewController:imagePicker];
[popoverController presentPopoverFromRect:CGRectMake(0.0, 0.0, 400.0, 300.0)
inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionAny
animated:YES];
}
//Done button on top
- (void)navigationController:(UINavigationController *)navigationController
willShowViewController:(UIViewController *)viewController
animated:(BOOL)animated
{
//NSLog(#"Inside navigationController ...");
if (!doneButton)
{
doneButton = [[UIBarButtonItem alloc] initWithTitle:#"Done"
style:UIBarButtonItemStyleDone
target:self action:#selector(saveImagesDone:)];
}
viewController.navigationItem.rightBarButtonItem = doneButton;
}
- (IBAction)saveImagesDone:(id)sender
{
//NSLog(#"saveImagesDone ...");
[popoverController dismissPopoverAnimated:YES];
}
-(void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingImage : (UIImage *)image
editingInfo:(NSDictionary *)editingInfo
{
//DONT DISMISS
//[picker dismissModalViewControllerAnimated:YES];
//[popoverController dismissPopoverAnimated:YES];
IMAGE_COUNTER = IMAGE_COUNTER + 1;
imageView.image = image;
// Get the data for the image
NSData* imageData = UIImageJPEGRepresentation(image, 1.0);
// Give a name to the file
NSString* incrementedImgStr = [NSString stringWithFormat: #"UserCustomPotraitPic%d.jpg", IMAGE_COUNTER];
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* documentsDirectory = [paths objectAtIndex:0];
// Now we get the full path to the file
NSString* fullPathToFile2 = [documentsDirectory stringByAppendingPathComponent:incrementedImgStr];
// and then we write it out
[imageData writeToFile:fullPathToFile2 atomically:NO];
}
//Now use this code to get to user selected pictures. Call it from wherever you want in your code
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask ,YES);
NSString* documentsPath = [paths objectAtIndex:0];
NSString* dataFile = [documentsPath stringByAppendingPathComponent:#"UserCustomPotraitPic1.jpg"];
NSData *potraitImgData = [NSData dataWithContentsOfFile:dataFile];
backgroundImagePotrait = [UIImage imageWithData:potraitImgData];
Apple has provided api for this. It is called ALAssetsLibrary.
Using this you can select multiple images/ videos and other operations that you do using photo application on iOS device.
As in documentation Apple says:
Assets Library Framework
Introduced in iOS 4.0, the Assets Library framework
(AssetsLibrary.framework) provides a query-based interface for
retrieving photos and videos from the user’s device. Using this
framework, you can access the same assets that are normally managed by
the Photos application, including items in the user’s saved photos
album and any photos and videos that were imported onto the device.
You can also save new photos and videos back to the user’s saved
photos album.
Here are few links where you can learn more. Now to use it you can search for ALAssetsLibrary.
Assets Library Reference
http://www.fiveminutes.eu/accessing-photo-library-using-assets-library-framework-on-iphone/
Starting with iOS 14, multiple image selection is now supported in the new Photos picker. Here is sample code from Apple: Selecting Photos and Videos in iOS.
I use ALAssetsLibrary and rolled my own UI. The problem with UIImagePickerController is that it says you are supposed to dismiss the view controller in the didFinishPickingMediaWithInfo callback, so hacking multiple selection by not dismissing may run into problems. I know I did when I first tried it. I can't recall exactly what went wrong, but there were cases where UIImagePickerController simply stopped working if I didn't dismiss it like the docs say.
So I created an entire app and it works flawlessly the way I envisioned. Created an update that uses UIImages, and that works perfectly as well ONLY ON iOS 4 and above. For some reason the exact same code will not work the same on 3.0. Since the original app is on the store at min OS being 3, I do not want to just cut off my user base because of some silly mistake on my part. I'm not doing anything new, so it should all be backwards compatible.
Basically the app takes an image chosen from either the camera or the photo album and then saves it, and displays the image on the screen. When you go to the next screen it pulls the image file off the disk and displays it in the image view on the next screen. Again, works fine on iOS4 and above.
Using the 3.0 sim on an older version of xcode, it just will not function the same way. I know allowImageEditing changed to allowEditing, so I allowed for that, but everything else it seems according to the docs, should work on iOS 3 and above.
Below is my going to photo album and returning.
-(IBAction) getPhotoFromAlbum {
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
if (editingSwitch.on) {
#ifdef __IPHONE_3_0
picker.allowsImageEditing = YES;
#else
picker.allowsEditing = YES;
#endif
} else if (!editingSwitch.on) {
#ifdef __IPHONE_3_0
picker.allowsImageEditing = NO;
#else
picker.allowsEditing = NO;
#endif
}
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentModalViewController:picker animated:YES];
[picker release];
}
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
[picker dismissModalViewControllerAnimated:YES];
UIImage *image = nil;
if (editingSwitch.on) {
image = [info objectForKey:#"UIImagePickerControllerEditedImage"];
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:isImageEdited];
} else if (!editingSwitch.on) {
image = [info objectForKey:#"UIImagePickerControllerOriginalImage"];
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:isImageEdited];
}
imageView.image = [self imageWithImage:image];
imageView.hidden = NO;
buttonPreview.hidden = YES;
[NSThread detachNewThreadSelector:#selector(myThreadSavingImage) toTarget:self withObject:nil];
[activitySaving startAnimating];
When I debug, it seems the info that is coming back from the picker only has 1 key. When it sets the image, the image is blank. Basically no image ever comes back and if for some rare occasion it does, like when I edit the picture and not just use the original, it does not show up on the next page.
Hopefully everyone can help as the app is finished besides this 3.0 issue and its frustrating as I want to get it out soon.
Turns out the answer is that it was not working on the simulator due to the updates to the xcode program. When actually installed onto a 3.0 device, the code worked perfectly.
Hey guys i was curious if anybody could give me a very brief description of how to make an app record video in iOs 4. I know how to do all the media and whatnot using the os 3 method of using the UIImagePickerController but I do not know if that is still available in iOs4 and if not, could someone please give me a very brief description on how to do it using the new method? (No code required, but is more than welcome.)
-Thank you!
It's pretty straightforward.
I just made a view-based app with a single button on the interface to test this. The button's action is - (IBAction)shootButtonPressed;
You have to check if the device supports video recording and then configure the image picker controller to only shoot video. This code will only work on an actual device.
In the main view controller header, I made it conform to two protocols: UIImagePickerControllerDelegate and UINavigationControllerDelegate
Then I implemented the button press method like this;
- (IBAction)shootButtonPressed;
{
BOOL canShootVideo = [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera];
if (canShootVideo) {
UIImagePickerController *videoRecorder = [[UIImagePickerController alloc] init];
videoRecorder.sourceType = UIImagePickerControllerSourceTypeCamera;
videoRecorder.delegate = self;
NSArray *mediaTypes = [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypeCamera];
NSArray *videoMediaTypesOnly = [mediaTypes filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"(SELF contains %#)", #"movie"]];
BOOL movieOutputPossible = (videoMediaTypesOnly != nil);
if (movieOutputPossible) {
videoRecorder.mediaTypes = videoMediaTypesOnly;
[self presentModalViewController:videoRecorder animated:YES];
}
[videoRecorder release];
}
}
You also have to implement two more methods to handle when a movie's shot & chosen and when the user cancels the video camera picker.
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[self dismissModalViewControllerAnimated:YES];
// save the movie or something here, pretty much the same as doing a photo
NSLog(#"movie captured %#", info);
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
// process the cancellation of movie picker here
NSLog(#"Capture cancelled");
}
Super easy.
For more details, see the Multimedia Programming Guide --> About Audio and Video --> Using Video --> Recording and Editing Video. It's in the Apple Docs, although a little scattered for my taste.
I am using UIImagePickerController to record a video with the sourceType set to UIImagePickerControllerSourceTypeCamera.
I have set allowsEditing to true so that the video can be edited before the picker returns. But after I edit the video using the trimming interface and press "Pick", I only get back the original recording in the delegate, not the trimmed version. What am I doing wrong? I am using iPhone OS 3.1.3. I remember this used to work in an earlier version but it seems to be failing in the latest OS. Any help is appreciated?
By the way i confirmed that if the source of the video is UIImagePickerControllerSourceTypeSavedPhotosAlbum, the trimming works in version 3.1.3. So trimming with source as the camera is failing. Interestingly with the camera-roll/photos-album as the source, a "Choose" button appears and soon after clicking it, the controller displays a message saying the "Video is being trimmed ... ". I don't get this message when using the camera source.
Here is a snippet of the code I am using to record a video using the camera source.
- (void) recordVideo {
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.allowsEditing = YES;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
picker.mediaTypes = [NSArray arrayWithObject:(NSString *)kUTTypeMovie];
picker.videoQuality = UIImagePickerControllerQualityTypeHigh;
[self presentModalViewController:picker animated:YES];
[picker release];
}
My delegate implementation is as follows:
- (void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo: (NSDictionary *)info {
[picker dismissModalViewControllerAnimated:YES];
self.videoPath = [[info objectForKey:UIImagePickerControllerMediaURL] path];
...
}
Thanks a lot,
kris.
Just ran into this myself ... and found this post when looking for a solution.
looks like the only way around this is to copy the file to your app's directory, then open the UIVideoEditorController ...
Anyone know if this UIImagePickerController newly-captured video not being trimmed issue is a bug in the SDK, or are we doing something wrong?