2013-07-02 111 views
3

我想將iOS6中的所有視頻幀都轉換爲NSArray。 我使用此代碼:獲取視頻IOS的所有幀6

-(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設備,收到存儲器警告和最後崩潰上。

任何想法,解決方案?使用另一個更底層的框架/庫? C++? 對我來說非常重要!幫我! :)

謝謝!!!

+0

您可以使用[ ffmpeg框架](http://www.ffmpeg.org/)來提取幀的視頻 –

+0

是的,我知道,但我不知道如何。任何幫助?謝謝! :) –

+1

我不認爲iPhone內存可以與內存中的400張圖片共存,我建議將圖片保存到文檔目錄中。如果你仍然對一個例子感興趣,讓我知道,我會寫一個答案 – ekeren

回答

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); 
     } 
    }]; 
} 
+0

謝謝,但仍然崩潰,有什麼想法? –

+0

想一想,將更多的UIImage存入NSArray會使用大量的內存。 –

+0

當你看到崩潰日誌時,它是否告訴你操作系統殺死了你的應用程序以使用多少內存?如果是這樣,請考慮將圖像保存在較低分辨率,使用jpeg壓縮,和/或將它們異步寫入光盤,而不是將它們存儲在內存中。 – zimmryan

12

您需要:

  1. 使用CGImageRelease作爲@zimmryan提到
  2. 使用@autoreleasepool塊在循環
  3. 不將圖像存儲在內存中,它們存儲在您的文檔目錄

這是我要做的事:(注意我用的是同步的版本用於提取圖像時,建議立即進行刪除如果你選擇了異步版本)無論dn't

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); 
    } 
} 

編輯

你應該總是考慮創建的臨時對象很多時候使用@autoreleasepool(見https://developer.apple.com/library/mac/documentation/cocoa/conceptual/memorymgmt/articles/mmAutoreleasePools.html

+0

你能夠在UIImageView上查看'generatedImage'嗎? – Anil