【发布时间】:2017-08-02 17:57:40
【问题描述】:
我正在尝试哄骗 AVFoundation 从自定义 URL 中读取数据。自定义 URL 的东西有效。下面的代码创建一个带有电影文件的 NSData:
NSData* movieData = [NSData dataWithContentsOfURL:@"memory://video"];
我使用以下代码设置了一个 AVAssetResourceLoader 对象:
NSURL* url = [NSURL URLWithString:@"memory://video"];
AVURLAsset* asset = [[AVURLAsset alloc] initWithURL:url options:nil];
AVAssetResourceLoader* loader = [asset resourceLoader];
[loader setDelegate:self queue:mDispatchQueue];
调度队列是并发的。
然后我尝试从电影中提取第一帧:
AVAssetImageGenerator* imageGen = [AVAssetImageGenerator assetImageGeneratorWithAsset:asset];
CMTime time = CMTimeMakeWithSeconds(0, 600);
NSError* error = nil;
CMTime actualTime;
CGImageRef image = [imageGen copyCGImageAtTime:time
actualTime:&actualTime
error:&error];
if (error) NSLog(@"%@", error);
但是当我运行这个但我得到的代码时:
2013-02-21 10:02:22.197 VideoPlayer[501:907] Error Domain=AVFoundationErrorDomain Code=-11800 "The operation could not be completed" UserInfo=0x1f863090 {NSLocalizedDescription=The operation could not be completed, NSUnderlyingError=0x1e575a90 "The operation couldn’t be completed. (OSStatus error 268451843.)", NSLocalizedFailureReason=An unknown error occurred (268451843)}
委托方法的实现是:
- (BOOL)resourceLoader:(AVAssetResourceLoader *)resourceLoader shouldWaitForLoadingOfRequestedResource:(AVAssetResourceLoadingRequest *)loadingRequest
{
NSData* data = [NSData dataWithContentsOfURL:loadingRequest.request.URL];
[loadingRequest finishLoadingWithResponse:nil data:data redirect:nil];
return YES;
}
现在,我的问题是,我是否正确实施了该方法?有谁知道我做的是否正确?
谢谢。
编辑:我要完整获取的电影是单帧电影。
【问题讨论】:
-
现在看来 copyCGImageAtTime:actualTime:error: 调用不会等待委托方法完成(委托方法正在调度队列中运行)。所以问题就变成了如何确保在调用 copyCGImageAtTime:actualTime:error 之前已经加载了数据?
-
参见developer.apple.com/library/mac/#documentation/AudioVideo/… 上的“准备使用资产” - 您的缩略图生成代码应该在完成处理程序块中。
-
感谢您的评论,但是当我不需要更改 AVAssetResourceLoader 对象以及从 HTTP 或 FILE 类型的 URL 获取时,我的代码是正确的。我可以得到视频帧。我要解决的问题是如何从自定义 URL 获取它。有人告诉我 AVAssetResourceLoader 是关键,但我无法使用它。
-
loadingRequest.request.URL 是否等于@"memory://video"?如果 NSData 对象是您想要的,您可以通过使用 NSURLConnection 下载数据、将其写入磁盘然后使用
-[AVURLAsset initWithURL:options:]... 来规避整个问题,尽管这似乎是一个低于标准的解决方案。 -
网址正确。问题似乎是 resourceLoader:shouldWaitForLoadingOfRequestedResource: 和 copyCGImageAtTime:actualTime:error: 之间的竞争条件。后者在前者完成之前完成。我希望委托方法在后者结束之前完全完成。所以我一定是用错了。
标签: ios objective-c avfoundation