从用户的 iTunes 库中导出视频

Posted

技术标签:

【中文标题】从用户的 iTunes 库中导出视频【英文标题】:Exporting video from user's iTunes library 【发布时间】:2012-12-18 01:49:51 【问题描述】:

我已经搜索并阅读了文档,但我似乎无法找到解决我遇到的这个(看似简单的)问题的方法。我从用户的 iTunes 库中导出的歌曲运行良好,并且每次下载到用户的文档文件夹中都没有问题,但视频似乎无法正常工作。

我让它显示一个 MPMediaPickerController (allowsPickingMultipleItems = YES) 以允许用户从他们下载的库中选择视频或歌曲。完成后,这是我正在使用的相关代码:

- (void)mediaPicker:(MPMediaPickerController*)mediaPicker didPickMediaItems:(MPMediaItemCollection*)mediaItemCollection 
    AVAssetExportSession *exportSession;

    for (MPMediaItem *item in mediaItemCollection.items) 
        NSURL *assetUrl = [item valueForProperty:MPMediaItemPropertyAssetURL];
        MPMediaType type = [[item valueForProperty:MPMediaItemPropertyMediaType] intValue];
        if (type >= MPMediaTypeMovie) 
            exportSession = [[AVAssetExportSession alloc] initWithAsset:[AVAsset assetWithURL:assetUrl] presetName:AVAssetExportPreset640x480];
            exportSession.outputFileType = AVFileTypeQuickTimeMovie;
            filePath = [title stringByAppendingString:@".mov"];
            exportSession.outputURL = [NSURL fileURLWithPath:[[NSFileManager documentDirectory] stringByAppendingPathComponent:filePath]];
         // .. check for song-types here and set session up appropriately

        [exportSession exportAsynchronouslyWithCompletionHandler:^
            // never gets into AVAssetExportSessionStatusCompleted here for videos 
        
    

我每次得到的错误如下:

Error Domain=AVFoundationErrorDomain Code=-11820 "Cannot Complete Export" UserInfo=0x1e1a2180 NSLocalizedRecoverySuggestion=Try exporting again., NSLocalizedDescription=Cannot Complete Export

不是很有帮助。 :( 我觉得我可能在这里遗漏了一些明显的东西。我这样做的方法是否正确?我试图将其“强制”为 MOV 格式是否可能存在问题?或者可能需要不同的设置方式导出会话?

作为参考,我在 iPhone 5 上使用 ios 6.0.1 进行测试,baseSDK 为 6.0。提前感谢您对此提供的任何指导!

附加信息 #1:有些奇怪。如果我将 outputFileType 设置为“AVFileTypeAppleM4V”,它似乎会立即因“SIGTRAP”而崩溃。我想尝试 M4V,因为当我对assetURL 进行日志输出时,我会看到类似:ipod-library://item /item.m4v?id=12345。不知道这是否会有所不同,但奇怪的是,如果我尝试 m4v 格式,它就会像那样崩溃。可能是因为它不在支持的文件类型列表中(请参阅下一个信息点)。

附加信息#2:我得到的支持的文件类型(通过调用“supportedFileTypes”方法是:“com.apple.quicktime-movie”和“public.mpeg-4”。 “exportPresetsCompatibleWithAsset”包括所有视频,包括 m4a、低/中/高质量和特定尺寸的。我已经尝试了所有这些的每种组合,例如用于文件类型的 AVFileTypeQuickTimeMovie 和 AVFileTypeMPEG4,以及所有预设,包括低/中/高,以及所有维度。我总是会收到“无法完成导出”错误。

附加信息 #3:我也使用 5.1 的部署目标。但是,是的,我试过 6.0,它给出了同样的错误。 :(

附加信息 #4:如果需要了解,我正在测试的电影是“试播”电视节目,一个视频,是我在 iTunes 中看到的第一个免费视频。所以我下载了它以在这个应用程序中使用。

附加信息#5:不确定这是否重要,但“hasProtectedContent”方法为 AVAsset(如果我转换了 AVURLAsset)返回 YES。可能没有什么不同,但我想我会把它扔在那里。

【问题讨论】:

我不肯定,但我认为您的AVAssetExportSession :initWithAsset:presetName: 函数应该使用AVURLAsset 而不是AVAsset 调用。如果是这样,您需要将[AVAsset assetWithURL:assetUrl] 替换为[AVURLAsset URLAssetWithURL:assetUrl options:nil] 感谢您对此的回复。不幸的是,当我将 AVAsset 替换为您在我的 initWithAsset 代码行中复制的 AVURLAsset 时,我得到了相同的“无法完成导出”。 :( 我将预设保留为 AVAssetExportPresetLowQuality,将“shouldOptimizeForNetworkUse”设置为 YES,并将 outputFileType 设置为 AVFileTypeQuickTimeMovie(文件路径为 .mov)。不过,我很欣赏对此的回应。还有其他想法可以尝试吗?跨度> 【参考方案1】:

在尝试复制问题并进行一些测试后,我强烈怀疑受保护的内容是一个问题。原因如下:

我复制了您的代码,并在我的 iPod Touch(第 5 代,iOS 6.0.1)上对其进行了测试,但我没有来自媒体选择器,而是让它循环播放设备上的所有视频(7其中。)它工作得很好,并调用了完成处理程序并在应用程序沙箱的文档目录中制作了正确的 .mov 文件。我将 .mov 文件移到了我的 Mac 上,它们都播放了。

这些视频文件的 hasProtectedContent 为 NO。

所以我放置了一个从 iTunes 商店获得的视频文件,并确认它的 hasProtectedContent 为 YES。有趣的是,当我尝试从 MPMediaItemPropertyAssetURL 获取 URL 时,对于受保护/iTunes 获得的视频,我得到了 nil。

我强烈怀疑媒体保护是问题所在。

这是我使用的代码变体。我根本没有更改您的转换代码,只是提供 URL 的方式:

// select all the video files
MPMediaPropertyPredicate *predicate = [MPMediaPropertyPredicate predicateWithValue:[NSNumber numberWithInteger:MPMediaTypeMovie] forProperty:MPMediaItemPropertyMediaType];

MPMediaQuery *query = [[MPMediaQuery alloc] init];
[query addFilterPredicate:predicate];

NSArray *items = [query items];

// now go through them all to export them

NSString* title;
NSURL * url;
AVAssetExportSession *exportSession;
NSString *storePath;
AVAsset *theAsset;

// we fill put the output at this path
NSString *applicationDocumentsDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];


// loop through the items and export
for (MPMediaItem* item in items)

    title = [item valueForProperty:MPMediaItemPropertyTitle];
    url = [item valueForProperty:MPMediaItemPropertyAssetURL];

    NSLog(@"Title: %@, URL: %@",title,url);

    theAsset = [AVAsset assetWithURL:url];

    if ([theAsset hasProtectedContent]) 
        NSLog(@"%@ is protected.",title);
     else 
        NSLog(@"%@ is NOT protected.",title);
    

    exportSession = [[AVAssetExportSession alloc] initWithAsset:theAsset presetName:AVAssetExportPreset640x480];

    storePath = [applicationDocumentsDir stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.mov",title]];

    exportSession.outputFileType = AVFileTypeQuickTimeMovie;

    exportSession.outputURL = [NSURL fileURLWithPath:storePath];

    [exportSession exportAsynchronouslyWithCompletionHandler:^
        NSLog(@"done!");
    ];


出于好奇,您是否正在检查AVAsset exportable 标志?

【讨论】:

精准。昨晚与苹果公司的人确认。我之前没有检查过“isExportable”标志,但现在我快速检查了一下,它为这个资产返回了“NO”。苹果表示,任何具有受保护(DRM)内容的媒体,即可以通过“hasProtectedContent”属性检查,不支持播放、导出、获取元数据等操作。但是,我们自己创建的视频内容应该没问题。我有点担心,目前正在寻找一个记录在案的地方?!浪费了很多时间。无论如何,感谢您的回答并抽出宝贵的时间!

以上是关于从用户的 iTunes 库中导出视频的主要内容,如果未能解决你的问题,请参考以下文章

如何在 iOS 应用中导出音频文件?

在没有 MPMediaPickerController 的情况下访问用户 iTunes 库

Macbook air里的itunes如何使用?

如何从 iTunes 库中修剪或裁剪音乐

将 iTunes applescript 转换为使用更新的 iTunes 库框架

iTunes 连接应用预览视频