Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problem saving recorded video on iPhone's library

I am trying to save a recorded video to the library using the UIImagePickerController delegate. It works fine for pictures but it doesn't save if it's a video, plus after trying to save a video if I open the Photos app, I get a message "Please wait. Updatring library", and a progress bar with the label "Rebuilding library". My photo library is restored but the video was not added to it.

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {


    NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];

     if ([mediaType isEqualToString:@"public.image"]){
          UIImage *picture = [info objectForKey:UIImagePickerControllerOriginalImage];
          UIImageWriteToSavedPhotosAlbum(picture, nil, nil, nil);
    } 
     else if ([mediaType isEqualToString:@"public.movie"]){

          NSString* m_objMediaURL= [info objectForKey:UIImagePickerControllerMediaURL];
          NSLog(@"URL is %@", m_objMediaURL);
          UISaveVideoAtPathToSavedPhotosAlbum(m_objMediaURL, nil, nil, nil);
     }

     [self dismissModalViewControllerAnimated:YES];

}

The NSLog above outputs the following:

URL is 
file://localhost/private/var/mobile/Applications/3800A5FB-2A96-4A7A-85DF-B635E8D9A66C/tmp/capture-T0x1061f0.tmp.JMdxHq/capturedvideo.MOV

Has anyone implemented such method and can point me to the right direction please?

Thank you.

like image 389
Rafael Avatar asked Nov 02 '10 13:11

Rafael


2 Answers

I think I see an issue.

NSString* m_objMediaURL= [info objectForKey:UIImagePickerControllerMediaURL];

Is the wrong type. My properly working code uses:

NSURL *url = [[[info objectForKey:UIImagePickerControllerMediaURL] copy] autorelease];

I copy it instead of retaining it because of some issues I have had in low memory situations after the picker view is dismissed. Although the save method you use might work, I use the newer and better (because of the callback block):

ALAssetsLibrary* library = [[[ALAssetsLibrary alloc] init] autorelease];
[library writeVideoAtPathToSavedPhotosAlbum:url
                            completionBlock:^(NSURL *assetURL, NSError *error){/*notify of completion*/}];

Also, you should be using kUTTypeMovie and kUTTypeImage instead of hard coding @"public.image.

like image 115
Peter DeWeese Avatar answered Sep 28 '22 06:09

Peter DeWeese


I found the problem thanks to Peter's help. Turns out that [info objectForKey:UIImagePickerControllerMediaURL] returns a NSURL and not a NSString. So in the end here's how my method looks like

    ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];

    NSURL *videoURL= [info objectForKey:UIImagePickerControllerMediaURL];

    if ([library videoAtPathIsCompatibleWithSavedPhotosAlbum:videoURL])
    {
        [library writeVideoAtPathToSavedPhotosAlbum:videoURL


                                    completionBlock:^(NSURL *assetURL, NSError *error){}
            ];
        } 
[library release];

This method uses the new ALAssetsLibrary framework. The whole method, which supports saving a picture or movie, follows:

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {


    ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
    NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];

    if ([mediaType isEqualToString:@"public.image"]){

        UIImage *picture= [info objectForKey:UIImagePickerControllerOriginalImage];
        NSDictionary *metadata = [info objectForKey:UIImagePickerControllerMediaMetadata];

        [library writeImageToSavedPhotosAlbum:[picture CGImage] metadata:metadata 
                              completionBlock:^(NSURL *assetURL, NSError *error){}
        ];

    } 
    else if ([mediaType isEqualToString:@"public.movie"]){

        NSURL *videoURL= [info objectForKey:UIImagePickerControllerMediaURL];

        if ([library videoAtPathIsCompatibleWithSavedPhotosAlbum:videoURL])
        {
            [library writeVideoAtPathToSavedPhotosAlbum:videoURL
                                        completionBlock:^(NSURL *assetURL, NSError *error){}
            ];
        } 

    }


    [library release];    
    [self dismissModalViewControllerAnimated:YES];
}
like image 32
Rafael Avatar answered Sep 28 '22 07:09

Rafael