3

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

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

    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,与我正在使用的设备兼容(即应该可以保存它)。

老实说,我不知道该怎么做。任何提示将不胜感激。谢谢

4

3 回答 3

9

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

在下面的示例中,我构建了一个在屏幕上有两个按钮的简单应用程序。一个调用onSaveBtn:,它只是抓取我在我的应用程序资源包中拥有的视频的 URL,并将其保存到用户保存的相册中。(不过,就我而言,我的视频确实YES从. 返回videoAtPathIsCompatibleWithSavedPhotosAlbum:。我没有任何视频不会返回。)

第二个按钮连接到onExportBtn:,它获取我们要保存的视频,创建一个AVAssetExportSession,将视频导出到临时目录,然后将导出的视频复制到保存的相册中。由于导出时间的原因,此方法确实比简单的复制需要更长的时间,但也许这可能是一个替代路径 - 检查结果videoAtPathIsCompatibleWithSavedPhotosAlbum:,如果是YES,则直接复制到相册。否则,导出视频,然后复制。

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

您可能还想查看这个问题,该问题探讨了您可能正在使用的设备上兼容的视频格式。

#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];
    }
}
于 2013-07-24T17:12:42.080 回答
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];
       }

}];

您可以在此处更改 url,我已用于 imagePickerController.. 看看它是否对您有帮助..

于 2013-07-24T06:16:42.090 回答
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");
}

干杯!

于 2014-05-01T14:50:30.623 回答