获取videoIOS 6的所有帧
我想要在iOS6中的video的所有帧到NSArray
。 我使用这个代码:
-(void) getAllImagesFromVideo { imagesArray = [[NSMutableArray alloc] init]; times = [[NSMutableArray alloc] init]; for (Float64 i = 0; i < 15; i += 0.033) // For 25 fps in 15 sec of Video { CMTime time = CMTimeMakeWithSeconds(i, 60); [times addObject:[NSValue valueWithCMTime:time]]; } [imageGenerator generateCGImagesAsynchronouslyForTimes:times completionHandler:^(CMTime requestedTime, CGImageRef image, CMTime actualTime, AVAssetImageGeneratorResult result, NSError *error) { if (result == AVAssetImageGeneratorSucceeded) { UIImage *generatedImage = [[UIImage alloc] initWithCGImage:image]; [imagesArray addObject:generatedImage]; } }]; }
在iPad模拟器上,延迟时间为90〜100秒,在iPad设备上,收到内存警告,最后崩溃。
任何想法,解决scheme? 使用另一个更底层的框架/库? C ++? 对我来说非常重要! 帮我! 🙂
谢谢!!!
你需要:
- 使用CGImageRelease作为@zimmryan提到的
- 在循环中使用@autoreleasepool块
- 不要将图像存储在内存中,将它们存储在文档目录中
这是我如何做到的:(注意我使用同步版本来提取图像,如果您selectasynchronous版本,则无关紧要)
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:url options:nil]; AVAssetImageGenerator *generator = [[AVAssetImageGenerator alloc] initWithAsset:asset]; generator.requestedTimeToleranceAfter = kCMTimeZero; generator.requestedTimeToleranceBefore = kCMTimeZero; for (Float64 i = 0; i < CMTimeGetSeconds(asset.duration) * FPS ; i++){ @autoreleasepool { CMTime time = CMTimeMake(i, FPS); NSError *err; CMTime actualTime; CGImageRef image = [generator copyCGImageAtTime:time actualTime:&actualTime error:&err]; UIImage *generatedImage = [[UIImage alloc] initWithCGImage:image]; [self saveImage: generatedImage atTime:actualTime]; // Saves the image on document directory and not memory CGImageRelease(image); } }
编辑 :
在创build大量临时对象时,您应该始终考虑使用@autoreleasepool(请参阅https://developer.apple.com/library/mac/documentation/cocoa/conceptual/memorymgmt/articles/mmAutoreleasePools.html )
听起来就像你从375张图片中遇到的内存问题。 试试这个,它可能会提供更好的内存pipe理。
-(void) getAllImagesFromVideo { imagesArray = [[NSMutableArray alloc] initWithCapacity:375]; times = [[NSMutableArray alloc] initWithCapacity:375]; for (Float64 i = 0; i < 15; i += 0.033) // For 25 fps in 15 sec of Video { [times addObject:[NSValue valueWithCMTime:CMTimeMakeWithSeconds(i, 60)]]; } [imageGenerator generateCGImagesAsynchronouslyForTimes:times completionHandler:^(CMTime requestedTime, CGImageRef image, CMTime actualTime, AVAssetImageGeneratorResult result, NSError *error) { if (result == AVAssetImageGeneratorSucceeded) { [imagesArray addObject:[UIImage imageWithCGImage:image]]; CGImageRelease(image); } }]; }