10

我想使用 AVPlayer 缓存渐进式下载视频。如何将 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):

4

2 回答 2

9

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

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 不支持我们正在寻找的功能。据我所知, AVAssetExportSession 在后台使用了 AVAssetReader ,并且在失败时只报告了一个更少描述性的错误。如果他们只是这样记录它肯定会很好。AVAssetExportSession 的文档没有提到任何关于需要本地的资产:

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

我知道这不是一个很好的答案,但它使调查稍微向前推进了一点。我仍然真的希望有某种方法可以做到这一点,因为显然我们并不是唯一一个想要这个功能的人。

于 2011-06-13T16:31:57.533 回答
0

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

这似乎是一个缺失的特征。文档中没有任何地方说明它不支持网络媒体的数据访问。在尝试运行 API 时,甚至 API 中的错误消息和其他内容也会变得奇怪且似乎不完整。很可能很快就会得到支持。

于 2011-07-05T17:52:06.707 回答