【问题标题】:Caching with AVPlayer and AVAssetExportSession使用 AVPlayer 和 AVAssetExportSession 进行缓存
【发布时间】:2011-09-09 16:29:52
【问题描述】:

我想使用 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):

【问题讨论】:

  • 嘿!你解决了吗?

标签: iphone ios video-streaming avfoundation avplayer


【解决方案1】:

我还没有使用 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

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

【讨论】:

  • 是的,我遇到了同样的问题。更糟糕的是, mediaAsset.exportable 是 YES !但它仍然会抛出“无法初始化...在非本地 URL”异常。
  • 您是只对音频感兴趣还是主要对音频感兴趣?因为如果是这样,可以通过连接 URL 加载系统、音频文件流服务和音频队列服务来实现。我现在正在研究一个解决方案,但它非常复杂。有兴趣吗?
  • 不幸的是,我需要缓存整个视频。不过谢谢 - 我会在几天内将您标记为已接受的答案。
  • 杰西,你能谈谈你的音频解决方案吗?或者分享一下吗?如果是,请通过电子邮件与我联系或在此处发表评论。
  • @RomanTemchenko:很抱歉,我从未真正完成该解决方案。这看起来很简单,但后来我对使用适当的元数据等向 AQS 提供编码数据包的所有细节都挂断了。由于那些低级 A/V 框架在某种程度上是一个记录不足的黑匣子,它不是对我来说很重要,我要花时间把它弄清楚。
【解决方案2】:

肯定它不适用于 iOS 4.X。有没有人试过让它在 iOS 5 Beta 上运行?

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-07-24
    • 1970-01-01
    • 2016-08-11
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    • 2017-02-25
    • 2015-04-04
    相关资源
    最近更新 更多