获取Video IOS 6的所有帧

Jav*_*aña 3 frame-rate objective-c image-generation avfoundation ios

我想在iOS6中获取视频的所有帧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];
     }
   }];
}
Run Code Online (Sandbox Code Playgroud)

在iPad模拟器上,延迟是90~100秒,在iPad设备上,收到内存警告,最后崩溃.

任何想法,解决方案?使用另一个更低级的框架/库?C++?对我来说非常重要!帮我!:)

谢谢!!!

eke*_*ren 12

你需要:

  1. 使用CGImageRelease作为@zimmryan提到
  2. 在循环中使用@autoreleasepool块
  3. 不要将图像存储在内存中,将它们存储在文档目录中

这就是我这样做的:(注意我使用同步版本来提取图像,如果选择异步版本则无关紧要)

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);
  }
}
Run Code Online (Sandbox Code Playgroud)

编辑:

在创建大量临时对象时,应始终考虑使用@autoreleasepool(请参阅https://developer.apple.com/library/mac/documentation/cocoa/conceptual/memorymgmt/articles/mmAutoreleasePools.html)


zim*_*yan 5

听起来你正在遇到375张图片的内存问题.试试这个,它可以提供更好的内存管理.

-(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);
       }
   }];
}
Run Code Online (Sandbox Code Playgroud)