【问题标题】:Copy downloaded video to camera roll将下载的视频复制到相机胶卷
【发布时间】:2013-07-23 05:16:02
【问题描述】:

尽管它看起来像一个简单的过程,但我现在尝试了 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,与我正在使用的设备兼容(即应该可以保存它)。

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

【问题讨论】:

  • 您是否验证过该视频与相机胶卷兼容?致电videoAtPathIsCompatibleWithSavedPhotosAlbum: 对您正在处理的视频有何看法?
  • 我已经按照@fa7d0 链接给出的提示进行操作,但没有成功。我还转储了 Documents 目录,文件就在那里。
  • 使用@JoshBuhler 建议的方法,我实际上得到了一个NO.. 但很奇怪,容器是一个mp4,应该可以保存它......跨度>
  • 而且无论如何,如果不兼容,保存操作不应该抛出错误吗?!

标签: iphone ios objective-c camera avfoundation


【解决方案1】:

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

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

第二个按钮连接到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 表示很酷的提示和 sn-p。这是一个很好的提示,我会尝试一下,看看会发生什么。那我告诉你……谢谢!
  • 好的,至少它使它适用于某些文件...谢谢!
【解决方案2】:

您在哪里提供块的 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.. 看看它是否对你有帮助..

【讨论】:

  • 这不正是我在问题中写的吗?
  • 这正是你写的......但我没有看到 URL 路径,那个路径在哪里,你在这里做的是,将一张图像保存在相机胶卷和文档目录中,你是提供文档目录的 URL 路径,但不提供相机胶卷...
  • 嗯,我打印了一个名为 localPath 的字符串(并且我已经将输出放在了:它显示了 Documents 目录中的路径)。然后我把它变成一个 NSURL 并尝试使用 ALAssetsLibrary 方法将它保存到相机胶卷中。我认为您不应该提供相机胶卷的路径,而且无论如何我看不到我应该在哪里指定它...
  • 我认为你应该在第一个块中写下,尽量不要打破块,它可能会有所帮助..
【解决方案3】:

这是一个简短的答案。

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

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

这是我用来将应用程序本地文件目录中的视频导出到相机胶卷的 sn-p:

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");
}

干杯!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-25
    • 1970-01-01
    • 2016-05-01
    • 2015-01-06
    • 2018-05-09
    • 2014-02-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多