使用带有ARC的AVAssetImageGenerator创建大量缩略图的问题

Cha*_*has 5 objective-c thumbnails avfoundation automatic-ref-counting

我已经查看了我能找到的关于此的想法的每个列表但是已经停留了几天了所以这里希望......

我正在尝试使用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代码,则不会发生这些行为.我出错的任何想法?

  1. 现在,添加到播放列表的每部电影都会被立即加载到物理内存中 - 因此应用程序内存占用量已经增加(100个电影没有缩略图代码= 40MB,缩略图(NSImages为32x18像素),相同的100部电影为750MB).

  2. 查看活动监视器 - >打开文件和端口,即使创建缩略图后,也会列出所有电影文件.这之前没有发生过 - 只列出了正在播放的电影.

  3. 缩略图创建完全锁定我的机器直到它完成 - 即使我在异步块中调用AVAssetImageGenerator - (CPU使用率从未超过35%).尝试一次阅读100部电影会出现磁盘访问问题吗?

  4. 缩略图创建非常不稳定.有时创建所有缩略图,但通常随机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;
            }
        }];
    }
Run Code Online (Sandbox Code Playgroud)

(注意:我在上个月左右使用相同的几个电影文件夹来开发应用程序.它们都是在应用程序中成功播放的本地有效文件.其中一些文件夹丢失包含一百多部电影嵌套在各种子文件夹中的文件).

非常感谢有人可以提供帮助.查斯.

dam*_*ian 0

我以这种方式使用时AVAssetImageGenerator也遇到了一些奇怪的问题(至少在 iOS 上)。在我看来,当与块/GCD API 结合使用时,它至少有些破损。不要异步加载所有内容,而是尝试创建一个在单个后台线程中运行的单个队列/循环,并以这种方式浏览电影。这也应该有助于降低内存使用量。