使用AVPlayer和AVAssetExportSession进行缓存

我想使用AVPlayer缓存渐进式下载video。 如何将AVPlayer的项目保存到磁盘? 我正在尝试在播放器的currentItem(完全加载)上使用AVAssetExportSession。 这段代码给了我“ AVAssetExportSessionStatusFailed(操作无法完成) ”:

AVAsset *mediaAsset = self.player.currentItem.asset; AVAssetExportSession *es = [[AVAssetExportSession alloc] initWithAsset:mediaAsset presetName:AVAssetExportPresetLowQuality]; NSString *outPath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"out.mp4"]; NSFileManager *fileManager = [NSFileManager defaultManager]; [fileManager removeItemAtPath:outPath error:NULL]; es.outputFileType = @"com.apple.quicktime-movie"; es.outputURL = [[[NSURL alloc] initFileURLWithPath:outPath] autorelease]; NSLog(@"exporting to %@",outPath); [es exportAsynchronouslyWithCompletionHandler:^{ NSString *status = @""; if( es.status == AVAssetExportSessionStatusUnknown ) status = @"AVAssetExportSessionStatusUnknown"; else if( es.status == AVAssetExportSessionStatusWaiting ) status = @"AVAssetExportSessionStatusWaiting"; else if( es.status == AVAssetExportSessionStatusExporting ) status = @"AVAssetExportSessionStatusExporting"; else if( es.status == AVAssetExportSessionStatusCompleted ) status = @"AVAssetExportSessionStatusCompleted"; else if( es.status == AVAssetExportSessionStatusFailed ) status = @"AVAssetExportSessionStatusFailed"; else if( es.status == AVAssetExportSessionStatusCancelled ) status = @"AVAssetExportSessionStatusCancelled"; NSLog(@"done exporting to %@ status %d = %@ (%@)",outPath,es.status, status,[[es error] localizedDescription]); }]; 

我怎样才能成功导出? 我正在考虑将mediaAsset复制到AVMutableComposition中,但也没有太多运气。

谢谢!

PS:以下是人们试图完成同样事情的一些问题(但是使用MPMoviePlayerController):

  • 缓存在MPMoviePlayerController中逐行下载的内容

  • 同时流式传输和保存video?

  • MPMoviePlayerController成功预加载后,将video缓存到磁盘

我还没有使用iOS 4.3 SDK,但我很想知道4.3下的mediaAsset.exportable的价值,如下所述:

http://developer.apple.com/library/ios/#releasenotes/AudioVideo/RN-AVFoundation/_index.html#//apple_ref/doc/uid/TP40010717-CH1-SW4

我已尝试对您的代码进行一些修改,例如从可用列表中获取预设名称和文件类型,但我收到的错误与您相同。

因此,我决定尝试更低级别的框架,因为文档声明您可以连接AVAssetReader和AVAssetWriter以获得与AVAssetExportSession相同的效果,除非有更多控制。 但是,以下代码:

 NSError *readerError = nil; AVAssetReader *reader = [AVAssetReader assetReaderWithAsset:mediaAsset error:&readerError]; if (readerError) NSLog(@"Error instantiating asset reader: %@", [readerError localizedDescription]); 

给出以下输出:

 *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[AVAssetReader initWithAsset:error:] Cannot initialize an instance of AVAssetReader with an asset at non-local URL 'http://example.com/test.mp3'' 

请注意,我使用工作url对其进行了测试,但已将其替换为上面的假url。 这对我来说就像iOS不支持我们正在寻找的function。 据我所知,AVAssetExportSession在底层使用AVAssetReader,只是在失败时报告的描述性错误要少得多。 如果他们只是这样记录它肯定会很好。 AVAssetExportSession的文档没有提到有关需要本地的资产的任何内容:

http://developer.apple.com/library/ios/#documentation/AVFoundation/Reference/AVAssetExportSession_Class/Reference/Reference.html#//apple_ref/occ/cl/AVAssetExportSession

我知道这不是一个很好的答案,但它将调查推向了一点点。 我仍然希望有一些方法可以做到这一点,因为显然我们并不是唯一想要这个function的人。

当然,它不适用于iOS 4.X. 有没有人试过让它在iOS 5 Beta上运行?

这似乎是一个缺失的胎儿。 文档中没有任何声明它不支持网络媒体的数据访问。 甚至错误消息和API中的其他东西都是奇怪的,并且在尝试运行时似乎是不完整的。 很可能很快就会得到支持。