使用AVPlayer和AVAssetExportSession进行缓存

tba*_*tba 9 iphone avfoundation video-streaming ios avplayer

我想使用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]);
    }];
Run Code Online (Sandbox Code Playgroud)

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

谢谢!

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

Jes*_*sen 9

我还没有使用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]);
Run Code Online (Sandbox Code Playgroud)

给出以下输出:

*** 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''
Run Code Online (Sandbox Code Playgroud)

请注意,我使用工作网址对其进行了测试,但已将其替换为上面的假网址.这对我来说就像iOS不支持我们正在寻找的功能.据我所知,AVAssetExportSession在引擎盖下使用了一个AVAssetReader,并且在失败时只报告一个描述性较差的错误.如果他们只是将其记录下来,那肯定会很好.AVAssetExportSession的文档没有提到有关需要本地的资产的任何内容:

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

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

  • 您是否只对音频感兴趣?因为如果是这样,可以通过连接URL加载系统,音频文件流服务和音频队列服务来实现.我现在正在研究解决方案,但它非常复杂.有兴趣吗? (4认同)