I have an app where I can shoot a video and then store it in core-data with some other data. It's stored as Transformable and "Store in External Record File". I get the video clip into an object called movie like this;
(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
movie = [info objectForKey:UIImagePickerControllerEditedImage];
Where I get stuck is to get a thumbnail from the movie. Using MPMoviePlayerController I have to have an URL, but the movie isn't stored anywhere yet. Plus finding the URL from the core-data is a mystery as well.
The closest help I can find here is Getting a thumbnail from a video url or data in iPhone SDK . But I get caught out on the URL issue.
I am saving it to core-data like this;
NSManagedObjectContext *context = [self managedObjectContext];
NSManagedObject *newMedia = [NSEntityDescriptioninsertNewObjectForEntityForName:#"Media" inManagedObjectContext:context];
[newMedia setValue:#"Video Clip " forKey:#"title"];
[newMedia setValue:now forKey:#"date_time"];
[newMedia setValue:movie forKey:#"movie"];
[newMedia setValue:[self generateImage] forKey:#"frame"];
I would be grateful if there is someone out there that can give me a pointer.
I used like this in my app
- (UIImage *)imageFromMovie:(NSURL *)movieURL atTime:(NSTimeInterval)time {
// set up the movie player
MPMoviePlayerController *mp = [[MPMoviePlayerController alloc]
initWithContentURL:movieURL];
mp.shouldAutoplay = NO;
mp.initialPlaybackTime = time;
mp.currentPlaybackTime = time;
// get the thumbnail
UIImage *thumbnail = [mp thumbnailImageAtTime:time
timeOption:MPMovieTimeOptionNearestKeyFrame];
// clean up the movie player
[mp stop];
[mp release];
return(thumbnail);
}
used like
imageView.image = [self imageFromMovie:fileURL atTime:10.0];
To get thumbnail from movie...
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
if ([[info objectForKey:#"UIImagePickerControllerMediaType"] rangeOfString:#"movie"].location!=NSNotFound)
{
MPMoviePlayerController *theMovie = [[MPMoviePlayerController alloc] initWithContentURL:[info objectForKey:#"UIImagePickerControllerMediaURL"]];
theMovie.view.frame = self.view.bounds;
theMovie.controlStyle = MPMovieControlStyleNone;
theMovie.shouldAutoplay=NO;
UIImage *imgTemp = [theMovie thumbnailImageAtTime:0 timeOption:MPMovieTimeOptionExact];
}
}
You can get your movie URL like this and then use this URL to get thumbnail using MPMoviePlayerController.
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
NSURL * movieURL = [info valueForKey:UIImagePickerControllerMediaURL] ;
. .. .
.. ..
}
Related
I am working on adding video to a chat application. The users can either share a video chosen from their files or record a new one to upload.
The issue I am having is differentiating between a video which has just been recorded and a video which has been selected as I want to save a just recorded video to their album when they upload it.
Currently my code looks like this:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
// This checks whether we are adding image or video (public.movie for video)
if ([[info objectForKey:UIImagePickerControllerMediaType] isEqualToString:#"public.image"]) {
UIImage * image = [info objectForKey:UIImagePickerControllerEditedImage];
[self sendImage:image];
}
else {
// SS-V
// If we are dealing with a video then we want to return to the chat view and post the video
NSURL * videoURL = (NSURL *)[info objectForKey:UIImagePickerControllerMediaURL];
// Send video to the chat view
[self sendVideo:[videoURL absoluteString]];
}
[tableView reloadData];
[picker dismissViewControllerAnimated:YES completion:Nil];
}
So I am getting the local url of the video and then uploading it to an external database.
I have also got this code:
// Save the recorded video to the iPhone
NSString * videoCompatibleString = [videoURL.absoluteString stringByReplacingOccurrencesOfString:#"file://" withString:#""];
if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(videoCompatibleString)) {
UISaveVideoAtPathToSavedPhotosAlbum (videoCompatibleString, self, nil, nil);
}
Which will save it to my phone library.
So now my only issue is how to differentiate between a video just taken and a video selected from my library already.
I was hoping there would be an elegant way of achieving this. Seemingly there isn't and so I set up an enum to record what I loaded the image picker with, if I loaded it with the camera then I knew that I would be taking the video or picture so should add it to the album:
In the header file:
typedef enum {
bPictureTypeCamera,
bPictureTypeAlbumImage,
bPictureTypeAlbumVideo,
} bPictureType;
// This allows us to see what kind of media is being sent to know if we need to save it to album
bPictureType _pictureType;
In the main file:
// If we have just taken the media then save it to the users camera
if (_pictureType == bPictureTypeCamera) {
[self saveMediaWithInfo:info];
}
With my save function checking if it is video or image and saving it:
- (void)saveMediaWithInfo: (NSDictionary *)info {
// Save image
if ([[info objectForKey:UIImagePickerControllerMediaType] isEqualToString:#"public.image"]) {
UIImageWriteToSavedPhotosAlbum([info objectForKey:UIImagePickerControllerEditedImage], self, nil, nil);
}
// Save Video
else {
// Make sure the video is in a compatible format to save
NSURL * videoURL = (NSURL *)[info objectForKey:UIImagePickerControllerMediaURL];
NSString * videoCompatibleString = [[videoURL absoluteString] stringByReplacingOccurrencesOfString:#"file://" withString:#""];
if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum (videoCompatibleString)) {
UISaveVideoAtPathToSavedPhotosAlbum (videoCompatibleString, self, nil, nil);
}
}
}
Now the neatest answer but it does what it needs to
I am trying to get the image filename from the camera. I have seen many, many posts about retrieving the filename using UIImagePickerControllerReferenceURL or UIImagePickerControllerMediaURL, but that only gets you a filename similar to: //asset/asset.JPG?id=D1D715A8-6956-49FF-AF07-CE60FE93AE32&ext=JPG. I believe this is because the image is not saved yet, thus a name like img0001.jpg in not available.
Does anyone know how to get the filename? I am as suing I need to do this after UIImageWriteToSavedPhotosAlbum, but I cannot seem to figure it out.
I have seen the question asked many times, but none seem to 'really' answer it, they just always give the filename from an image chosen from the picker not from the camera.
Thanks for any help
** UPDATE:
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[self.popoverController dismissPopoverAnimated:true];
NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
[self dismissViewControllerAnimated:YES completion:nil];
if ([mediaType isEqualToString:(NSString *)kUTTypeImage])
{
UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];
imageView.image = image;
if (newMedia)
{
UIImageWriteToSavedPhotosAlbum(image,
self,
#selector(image:finishedSavingWithError:contextInfo:),
nil);
NSURL *refURL = [info valueForKey:UIImagePickerControllerMediaURL];
// define the block to call when we get the asset based on the url (below)
ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *imageAsset)
{
ALAssetRepresentation *imageRep = [imageAsset defaultRepresentation];
NSLog(#"[imageRep filename] : %#", [imageRep filename]);
};
// get the asset library and fetch the asset based on the ref url (pass in block above)
ALAssetsLibrary* assetslibrary = [[ALAssetsLibrary alloc] init];
[assetslibrary assetForURL:refURL resultBlock:resultblock failureBlock:nil];
}
}
}
My code above, but when imageRep filename is logged it is null.
I am trying to develop an app that can record video then attach it to email.
Here's what I did, but it isn't working.
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
NSString *mediaType = [info objectForKey: UIImagePickerControllerMediaType];
[self dismissModalViewControllerAnimated:NO];
// Handle a movie capture
if (CFStringCompare ((__bridge_retained CFStringRef) mediaType, kUTTypeMovie, 0) == kCFCompareEqualTo) {
NSString *moviePath = [[info objectForKey:UIImagePickerControllerMediaURL] path];
if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(moviePath)) {
UISaveVideoAtPathToSavedPhotosAlbum(moviePath, self,
#selector(video:didFinishSavingWithError:contextInfo:), nil);
videoURL = [[NSURL URLWithString:moviePath] init];
}
}
}
For Attachment:
[tempMailCompose addAttachmentData:[NSData dataWithContentsOfURL:videoURL] mimeType:#"video/MOV" fileName:#"defectVideo.MOV"];
The video recording and saving it to Photo Library is working good, my problem is the attachment.
What could be wrong?
For attachment you must use NSData. in case video attachment you have to use MimeType #"video/quicktime".
For more clarification please refer apple documentation.
MFMailComposeViewController
For attachment in mail use the following code :
[tempMailCompose addAttachmentData:[NSData dataWithContentsOfURL:videoURL] mimeType:#"video/quicktime" fileName:#"defectVideo.MOV"];
and rest of part is ok, i think.
I figured it out, here:
I replaced this...
videoURL = [[NSURL URLWithString:moviePath] init];
With this...
videoURL = [[NSURL alloc] initFileURLWithPath:moviePath];
It's working now.
I have a simple App than you have the possibility to choose an existent video from photo library or you can take a video with UIImagePickerController.
I added the following code for when I make a new video with camera I can save it in photo Gallery if I need in the future.
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
// Get the selected Video.
NSURL *videoURL = [info objectForKey:UIImagePickerControllerMediaURL];
// Convert to Video data.
NSData *imageData = [NSData dataWithContentsOfURL:videoURL];
// Save Video to Photo Album
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
NSURL *recordedVideoURL= [info objectForKey:UIImagePickerControllerMediaURL];
if ([library videoAtPathIsCompatibleWithSavedPhotosAlbum:recordedVideoURL]) {
[library writeVideoAtPathToSavedPhotosAlbum:recordedVideoURL
completionBlock:^(NSURL *assetURL, NSError *error){}
];
}
[library release];
[picker dismissModalViewControllerAnimated:NO];
}
Now my issue is when I select a video from Photo Library this same video is duplicated as this code save always a new video.
Is it a way to detect if you selected the video from Photo Library ?
Before saving the video, check the imagePickerController's sourceType. Only save the video if sourceType is UIImagePickerControllerSourceTypeCamera.
if (picker.sourceType == UIImagePickerControllerSourceTypeCamera) {
// Save the video
}
I got a big performance issue using UIImagePickerController and saving the image on disk. I can't figure out what I am doing wrong. Here is my code:
- (void)imagePickerController:(UIImagePickerController *)pick
didFinishPickingMediaWithInfo:(NSDictionary *)info {
UIImage *image = [info objectForKey:#"UIImagePickerControllerOriginalImage"];
NSData *imageData = [NSData dataWithData:UIImagePNGRepresentation(image)];
iPixAppDelegate *delegate = (iPixAppDelegate *)[[UIApplication sharedApplication] delegate];
[delegate addPicture:imageData];
}
The addPicture method creates a new picture object that is initialized this way:
- (Picture*) initPicture:(NSData*)dat inFolder:(NSString*)pat {
self.data = dat;
NSDate *d = [NSDate date];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"yyyy-mm-dd hh-mm-ss"];
self.name = [[formatter stringFromDate:d] stringByAppendingString:#".png"]; //The name by default of a picture is the date it has been taken
[formatter release];
self.path = [pat stringByAppendingPathComponent:self.name];
if(![self fileExistsAtPath:self.path]){
[self.data writeToFile:self.path atomically:YES];
}
return self;
}
The UIImagePickerController is quite fast but the program becomes very slow when I save picture on the disk.
Any idea on what I am doing wrong?
I had a similar issue. The way I got round it was to handle the image from the picker in a seperate thread. My problem was the main thread handling my app/UI was crashing out when trying to close the picker and handle the image:
- (void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingImage:(UIImage *)image
editingInfo:(NSDictionary *)editingInfo
{
[[picker parentViewController] dismissModalViewControllerAnimated:YES];
NSLog(#"picker did finish");
[NSThread detachNewThreadSelector:#selector(useImage:) toTarget:self withObject:image];
}
Your problem might be due to you taking the original image.
The original image from the camera has a resolution of around 1200x1400, which is a lot of memory and will cause the device to crash if you try making a picture out of it (it will run out of memory).
I would suggest resizing the image to be smaller (the native 320x480).