获取IOS 6视频的所有帧

获取IOS 6视频的所有帧,ios,objective-c,avfoundation,frame-rate,image-generation,Ios,Objective C,Avfoundation,Frame Rate,Image Generation,我想将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 { C

我想将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];
     }
   }];
}
-(无效)从视频获取所有图像
{
imagesArray=[[NSMutableArray alloc]init];
times=[[NSMutableArray alloc]init];
对于(Float64 i=0;i<15;i+=0.033)//对于15秒视频中的25 fps
{
CMTime time=CMTimeMakeWithSeconds(i,60);
[times addObject:[NSValue valueWithCMTime:time]];
} 
[ImageGeneratorGenerateGimagesAsSynchronouslyFortimes:times completionHandler:^(CMTime requestedTime、CGImageRef image、CMTime actualTime、AVAssetImageGeneratorResult结果、NSError*错误){
如果(结果==AvassetimageGeneratorSucceed)
{
UIImage*GenerateImage=[[UIImage alloc]initWithCGImage:image];
[imagesArray addObject:generateImage];
}
}];
}
在iPad模拟器上延迟90~100秒,在iPad设备上,收到内存警告,最后崩溃

有什么想法,解决办法吗?使用另一个更低级的框架/库?C++? 这对我很重要!救救我!:)


谢谢

听起来您在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);
       }
   }];
}
-(无效)从视频获取所有图像
{
imagesArray=[[NSMutableArray alloc]initWithCapacity:375];
times=[[NSMutableArray alloc]initWithCapacity:375];
对于(Float64 i=0;i<15;i+=0.033)//对于15秒视频中的25 fps
{
[times addObject:[NSValue valueWithCMTime:CMTimeMakeWithSeconds(i,60)];
} 
[ImageGeneratorGenerateGimagesAsSynchronouslyFortimes:times completionHandler:^(CMTime requestedTime、CGImageRef image、CMTime actualTime、AVAssetImageGeneratorResult结果、NSError*错误){
如果(结果==AvassetimageGeneratorSucceed)
{
[imagesArray添加对象:[UIImage imageWithCGImage:image]];
CGImageRelease(图像);
}
}];
}
您需要:

  • 使用CGImageRelease,如@zimmryan所述
  • 在循环中使用@autoreleasepool块
  • 不要将图像存储在内存中,请将其存储在文档目录中
  • 我就是这样做的:(注意,我使用同步版本来提取图像,如果选择异步版本,应该没有关系)

    AVURLAsset*asset=[[AVURLAsset alloc]initWithURL:url选项:nil];
    AVAssetImageGenerator*generator=[[AVAssetImageGenerator alloc]initWithAsset:asset];
    generator.requestedTimeToleranceAfter=kCMTimeZero;
    generator.requestedTimeToleranceBefore=kCMTimeZero;
    对于(Float64 i=0;i
    编辑


    在创建很多临时对象时,你应该总是考虑使用@ AutoReleSeCo水池(参见)

    。你可以用来从视频中提取帧,我知道,但是我不知道如何。有什么帮助吗?谢谢!:)我不认为iPhone的内存可以容纳400个图像,我建议将图像保存在您的文档目录中。如果你仍然对一个例子感兴趣,让我知道,我会写一个例子answer@ekeren我使用其他方法,但我想看看你的答案!谢谢!;)补充说,你最终使用了什么?谢谢,但还是崩溃了,有什么想法吗?想想看,在NSArray中保存更多的UIImages会占用大量内存。当你查看崩溃日志时,它是否告诉你操作系统因为使用了太多内存而杀死了你的应用程序?如果是这样,请考虑以较低的分辨率保存图像,使用jpeg压缩,和/或将图像异步写入光盘,而不是将其存储在内存中。您可以通过设置imageGenerator.maximumSize=CGSizeMake(320,180)或任何其他大小而不是全分辨率来更改输出大小。您是否能够在UIImageView上查看“generatedImage”?
    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);
      }
    }