我正在尝试使用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
有没有人实施过这样的方法,可以指出我正确的方向吗?
谢谢。
答案 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*/}];
此外,您应该使用kUTTypeMovie
和kUTTypeImage
代替硬编码@"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);