在iPhone的库中保存录制的视频时出现问题

时间:2010-11-02 13:48:54

标签: iphone objective-c

我正在尝试使用UIImagePickerController委托将录制的视频保存到库中。它适用于图片但如果它是视频则无法保存,如果我打开照片应用程序后尝试保存视频,我会收到一条消息“请等待.Update字符串库”,以及带有标签的进度条“重建图书馆“。我的照片库已恢复,但视频未添加到其中。

- (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];

}

上面的NSLog输出以下内容:

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

有没有人实施过这样的方法,可以指出我正确的方向吗?

谢谢。

3 个答案:

答案 0 :(得分:6)

我想我发现了一个问题。

NSString* m_objMediaURL= [info objectForKey:UIImagePickerControllerMediaURL];

是错误的类型。我正常工作的代码使用:

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

我复制它而不是保留它,因为在拾取器视图被解除后我在低内存情况下遇到了一些问题。尽管您使用的保存方法可能有效,但我使用的是更新更好(因为回调块):

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

此外,您应该使用kUTTypeMoviekUTTypeImage代替硬编码@"public.image

答案 1 :(得分:3)

感谢彼得的帮助,我发现了这个问题。事实证明[info objectForKey:UIImagePickerControllerMediaURL]返回NSURL而不是NSString。所以最后我的方法看起来像

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

    NSURL *videoURL= [info objectForKey:UIImagePickerControllerMediaURL];

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


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

此方法使用新的ALAssetsLibrary框架。支持保存图片或电影的整个方法如下:

- (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];
}

答案 2 :(得分:1)

为什么你将nil,nil,nil传递给方法 - 如果传递更多选项,它会告诉你错误;)

尝试这样的事情:

    UISaveVideoAtPathToSavedPhotosAlbum(m_objMediaURL, self, @selector(video:didFinishSavingWithError:contextInfo:), nil);

以及稍后在你班上的这个方法

- (void)video:(NSString *)videoPath didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo {
    // Let's see what happened
    NSLog(@"path : %@", path);
    NSLog(@:error : %@", error);
}

希望它的输出可以帮助你:)


编辑:

再次阅读the docs,您是否运行此方法检查它是否为有效视频?

BOOL isVideoOK = UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(m_objMediaURL);
if (NO == isVideoOK)
    NSLog(@"Video at %@ is not compatible", m_objMediaURL);