我已经查看了我能找到的关于此的想法的每个列表,但现在已经停留了几天所以这里希望......
我正在尝试使用AVAssetImageGenerator一次创建大量视频缩略图(100左右)。 虽然测试我总是使用相同的电影文件,但过程(看似)随机成功或失败,加上我现在将所有电影一次性加载到物理内存中,这是我不想要的。我显然做错了什么但无法弄清楚是什么 - 并且在ARC下无法手动管理内存。
背景; 它是一个使用ARC(Xcode 4.2.1,OSX 10.7.2,MBP 2.4GHz i5,4GB RAM)的AVFoundation视频播放器。 它有一个播放列表样式界面,允许您将电影文件的文件夹拖到它。它通过它给出的路径进行递归,然后输出有效的电影并将它们添加到列表中。 电影由Movie类表示,该类具有使用文件路径初始化的AVAsset成员变量(movieAsset)。到目前为止一切都很好 - 一切正常,电影可以播放,只有正在播放的电影是在物理记忆中。 我在Movie类中添加了一个-createThumbnail方法,该方法在Movie的init方法中调用(下面的代码片段)。 随着这段代码的添加,我得到了一些我无法根除的行为 - 如果我不调用下面的-createThumbnail代码,则不会发生这些行为。我出错的任何想法?
添加到播放列表的每部电影现在都会立即加载到物理内存中 - 因此应用程序内存占用率已经上升(100个电影没有缩略图代码= 40MB,缩略图(NSImages为32x18像素)750MB同样的100部电影)。
查看活动监视器 - >打开文件和端口,即使缩略图创建完成后,也会列出所有电影文件。之前没有发生 - 只列出了正在播放的电影。
缩略图创建完全锁定我的机器直到它完成 - 即使我在异步块中调用AVAssetImageGenerator - (CPU使用率从未超过35%)。尝试一次阅读100部电影会出现磁盘访问问题吗?
缩略图创建非常不稳定。有时创建所有缩略图,但通常随机30-70%不是。也许还有磁盘访问问题?
我对OOP和Obj-C很新,所以可能会犯一个新手的错误 - 但我无法追踪它......
另外值得注意的是,“错误创建缩略图”和“错误查找持续时间”NSLogs永远不会被调用...
-(void)createThumbnail{
NSArray *keys = [NSArray arrayWithObject:@"duration"];
[movieAsset loadValuesAsynchronouslyForKeys:keys completionHandler:^() {
NSError *error = nil;
AVKeyValueStatus valueStatus = [movieAsset statusOfValueForKey:@"duration" error:&error];
switch (valueStatus) {
case AVKeyValueStatusLoaded:
if ([movieAsset tracksWithMediaCharacteristic:AVMediaTypeVideo]) {
AVAssetImageGenerator *imageGenerator = [AVAssetImageGenerator assetImageGeneratorWithAsset:movieAsset];
Float64 movieDuration = CMTimeGetSeconds([movieAsset duration]);
CMTime middleFrame = CMTimeMakeWithSeconds(movieDuration/2.0, 600);
CGImageRef imageForThumbnail = [imageGenerator copyCGImageAtTime:middleFrame actualTime:NULL error:NULL];
if (imageForThumbnail != NULL) {
NSSize sizeOption = NSMakeSize(32, 18);
self.thumbnail = [[NSImage alloc] initWithCGImage:imageForThumbnail size:sizeOption];
NSLog(@"Thumbnail created for %@", [self filenameString]);
}
else{
NSLog(@"-----Error creating thumbnail for %@", [self filenameString]);
}
CGImageRelease(imageForThumbnail);
}
break;
case AVKeyValueStatusFailed:
NSLog(@"Error finding duration");
break;
case AVKeyValueStatusCancelled:
NSLog(@"Cancelled finding duration");
break;
}
}];
}
(注意:我在上个月左右使用相同的几个电影文件夹来开发应用程序。它们都是在应用程序中成功播放的本地有效文件。其中一些文件夹丢失了包含一百个电影文件嵌套在各个子文件夹中。)
非常感谢有人可以提供帮助。 查斯。
答案 0 :(得分:0)
以这种方式使用AVAssetImageGenerator
时我也遇到了一些奇怪的问题(至少在iOS上)。在与blocks / GCD API结合使用时,在我看来至少会有点破碎。不是异步加载所有内容,而是尝试制作一个在单个后台线程中运行的队列/循环,并以这种方式浏览电影。这也应该有助于降低内存使用率。