将下载的视频复制到相机胶卷

时间:2013-07-23 22:18:29

标签: iphone ios objective-c camera avfoundation

即使它看起来像一个简单的程序,现在是3个小时我正在尝试但没有成功。我可能错过了一些非常愚蠢的东西。

所以,我有这个应用程序从互联网上下载视频。视频正确存储在本地,因为我可以播放它们提供本地网址。但是,我无法成功将视频复制到相机胶卷。这是我的工作:

    ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
    ALAssetsLibraryWriteVideoCompletionBlock videoWriteCompletionBlock =
    ^(NSURL *newURL, NSError *error) {
        if (error) {
            NSLog( @"Error writing image with metadata to Photo Library: %@", error );
        } else {
            NSLog( @"Wrote image with metadata to Photo Library %@", newURL.absoluteString);
        }
    };

    NSLog(@"file %@", localPath);
    NSURL *url = [NSURL fileURLWithPath:localPath isDirectory:NO];
    [library writeVideoAtPathToSavedPhotosAlbum:url
                                completionBlock:videoWriteCompletionBlock];

但我得到的输出是:

2013-07-24 00:13:32.094 App[1716:907] file /var/mobile/Applications/70C18C4E-9F97-4A6A-B63E-1BD19961F010/Documents/downloaded_video.mp4
2013-07-24 00:13:32.374 App[1716:907] Wrote image with metadata to Photo Library (null)

当然,文件未保存在相机胶卷中。它是一个简单的mp4,与我正在使用的设备兼容(即应该可以保存它)。

老实说,我不知道该怎么做。任何提示都将受到高度赞赏。感谢

3 个答案:

答案 0 :(得分:9)

我可能已经为您找到了解决方法。你试过AVAssetExportSession吗?

在下面的示例中,我构建了一个简单的应用程序,屏幕上有两个按钮。一个人调用onSaveBtn:,它只是抓取我在应用资源包中的视频的网址,并将其保存到用户保存的相册中。 (虽然,在我的情况下,我的视频会从YES返回videoAtPathIsCompatibleWithSavedPhotosAlbum:。我没有任何其他视频也没有返回。)

第二个按钮连接到onExportBtn:,它会获取我们要保存的视频,创建AVAssetExportSession,将视频导出到临时目录,然后将导出的视频复制到已保存的照片专辑。由于导出时间,此方法确实比简单副本花费的时间更长,但也许这可能是备用路径 - 检查videoAtPathIsCompatibleWithSavedPhotosAlbum:的结果,如果YES,则直接复制到相册。否则,导出视频,然后复制。

如果没有一个视频文件没有返回NO兼容性调用,我不是100%确定这对你有用,但值得一试。

您可能还需要check out this question,它会探讨您可能正在使用的设备上兼容的视频格式。

#import <AVFoundation/AVFoundation.h>
#import <AssetsLibrary/AssetsLibrary.h>

- (IBAction)onSaveBtn:(id)sender
{
    NSURL *srcURL = [[NSBundle mainBundle] URLForResource:@"WP_20121214_001" withExtension:@"mp4"];
    [self saveToCameraRoll:srcURL];
}

- (IBAction)onExportBtn:(id)sender
{
    NSURL *srcURL = [[NSBundle mainBundle] URLForResource:@"WP_20121214_001" withExtension:@"mp4"];
    AVAsset *srcAsset = [AVAsset assetWithURL:srcURL];

    // create an export session
    AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:srcAsset presetName:AVAssetExportPresetHighestQuality];

    // Export the file to a tmp dir
    NSString *fileName = [srcURL lastPathComponent];
    NSString *tmpDir = NSTemporaryDirectory();
    NSURL *tmpURL = [NSURL fileURLWithPath:[tmpDir stringByAppendingPathComponent:fileName]];

    exportSession.outputURL = tmpURL;
    exportSession.outputFileType = AVFileTypeQuickTimeMovie;

    [exportSession exportAsynchronouslyWithCompletionHandler:^{       
        // now copy the tmp file to the camera roll
        switch ([exportSession status]) {
            case AVAssetExportSessionStatusFailed:
                NSLog(@"Export failed: %@", [[exportSession error] localizedDescription]);
                break;
            case AVAssetExportSessionStatusCancelled:
                NSLog(@"Export canceled");
                break;
            case AVAssetExportSessionStatusCompleted:
                NSLog(@"Export successful");
                [self saveToCameraRoll:exportSession.outputURL];
                break;
            default:
                break;
        }
    }];
}

- (void) saveToCameraRoll:(NSURL *)srcURL
{
    NSLog(@"srcURL: %@", srcURL);

    ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
    ALAssetsLibraryWriteVideoCompletionBlock videoWriteCompletionBlock =
    ^(NSURL *newURL, NSError *error) {
        if (error) {
            NSLog( @"Error writing image with metadata to Photo Library: %@", error );
        } else {
            NSLog( @"Wrote image with metadata to Photo Library %@", newURL.absoluteString);
        }
    };

    if ([library videoAtPathIsCompatibleWithSavedPhotosAlbum:srcURL])
    {
        [library writeVideoAtPathToSavedPhotosAlbum:srcURL
                                    completionBlock:videoWriteCompletionBlock];
    }
}

答案 1 :(得分:0)

您在哪里提供该块的URL。 我想你需要这样做..

NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
NSURL *videoURL = [info objectForKey:UIImagePickerControllerMediaURL];

ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library writeVideoAtPathToSavedPhotosAlbum:videoURL completionBlock:^(NSURL *assetURL, NSError *error){
       /*notify of completion*/
       NSLog(@"AssetURL: %@",assetURL);
       NSLog(@"Error: %@",error);
       if (!error) {
            //video saved

       }else{
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:error.domain delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
                [alert show];
                [alert release];
       }

}];

你可以在这里更改网址,我用过imagePickerController .. 看看它是否有助于你......

答案 2 :(得分:0)

这是一个较短的答案。

就我而言,我已经使用AFNetworking从URL下载视频,并在下载操作的downloadCompletedBlock中,responseObject返回下载文件。记录responseObject会返回下载视频的完整文件路径。

如果您使用其他方法下载视频,只需将responseObject替换为视频的完整文件路径,可能使用通常的NSSearchPathForDirectoriesInDomains方法。

以下是我用于将应用程序本地文件目录中的视频导出到相机胶卷的代码段:

NSURL *responseObjectPath = [NSURL URLWithString:responseObject];
// If video is compatible with Camera Roll
if ([[ALAssetsLibrary new] videoAtPathIsCompatibleWithSavedPhotosAlbum:responseObjectPath])
{
    // Export to Camera Roll
    [[ALAssetsLibrary new] writeVideoAtPathToSavedPhotosAlbum:responseObjectPath completionBlock:nil];
}
else
{
    NSLog(@"Incompatible File Type");
}

干杯!