2012-06-08 2 views
5

я пытаюсь преобразовать все видео в последовательность изображений со скоростью 60 кадров в секунду, что означает 60 изображений, генерируемых в секунду видео ...IOS AVFoundation - Преобразование видео в изображения на 60 кадров в секунду

Для сделайте это, я использую AVAssetImageGenerator и метод generateCGImagesAsynchronouslyForTimes ...

Все идет хорошо, за исключением того, что у меня возникают серьезные проблемы с производительностью, регулирующие время выполнения пакетной обработки (приблизительно 5 минут на 13 секунд видео). ..

Кроме того, выше следующего размера CGSizeMake (512, 324), я испытываю сбои. ..

У кого-нибудь уже есть опыт работы с этим видом обработки и он знает, как уменьшить это выполнение времени, а также возможность извлекать изображения с более высоким разрешением?

Ниже приведен код, я тестирую ...

NSURL *movieURL = [NSURL fileURLWithPath:getCaptureMoviePath()]; 

AVURLAsset *asset=[[AVURLAsset alloc] initWithURL:movieURL options:nil]; 
AVAssetImageGenerator *generator = [[AVAssetImageGenerator alloc] initWithAsset:asset]; 
generator.appliesPreferredTrackTransform=TRUE; 
generator.requestedTimeToleranceAfter=kCMTimeZero; 
generator.requestedTimeToleranceBefore=kCMTimeZero; 
NSMutableArray *thumbTimes=[NSMutableArray arrayWithCapacity:asset.duration.value]; 

for(int t=0;t < asset.duration.value;t=t+2) { 
    CMTime thumbTime = CMTimeMake(t, asset.duration.timescale); 
    NSLog(@"Time Scale : %d ", asset.duration.timescale); 
    NSValue *v=[NSValue valueWithCMTime:thumbTime]; 
     [thumbTimes addObject:v]; 
} 
NSLog(@"thumbTimes array contains %d objects : ", [thumbTimes count]); 
[asset release]; 
AVAssetImageGeneratorCompletionHandler handler = ^(CMTime requestedTime, CGImageRef im, CMTime actualTime, AVAssetImageGeneratorResult result, NSError *error) { 
    if (result != AVAssetImageGeneratorSucceeded) { 
     NSLog(@"couldn't generate thumbnail, error:%@", error); 
    } else { 
     NSLog(@"actual time: %lld/%d (requested: %lld/%d)",actualTime.value,actualTime.timescale,requestedTime.value,requestedTime.timescale); 
     NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; 
     [formatter setDateFormat:@"yyyyMMdd-HHmmss"]; 
     NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
     NSString *documentsDirectory = [paths objectAtIndex:0]; 
     NSString *filename = [NSString stringWithFormat:@"%@.png", [formatter stringFromDate:[NSDate date]]]; 
     NSString *filepath = [documentsDirectory stringByAppendingPathComponent:filename]; 
     CFURLRef url = (CFURLRef)[NSURL fileURLWithPath:filepath]; 
     CGImageDestinationRef destination = CGImageDestinationCreateWithURL(url, kUTTypePNG, 1, NULL); 
     CGImageDestinationAddImage(destination, im, nil); 
     if (!CGImageDestinationFinalize(destination)) {  
      NSLog(@"Failed to write image to %@", filepath); 
     } 
     CFRelease(destination); 
    } 
    //[generator release]; 
}; 
CGSize maxSize = CGSizeMake(512, 324); 
generator.maximumSize = maxSize; 

[generator generateCGImagesAsynchronouslyForTimes:thumbTimes completionHandler:handler]; 

Благодарим Вас заранее,

J.

+0

У меня такая же проблема, кроме как в моем случае. Я пытаюсь нарезать около 14 очень коротких видеоклипов. Вы когда-нибудь выясняли какие-либо возможные оптимизации? – afrederick

ответ

6

Hey @Sooriah Joel попробуйте использовать следующий код. Он отлично работает для меня.

- (void)generateCMTimesArrayOfAllFramesUsingAsset:(AVURLAsset *)asset 
{ 
    if (cmTimeArray.count>0) { 
     [cmTimeArray removeAllObjects]; 
    } 
    //Generate all frames present in video 
    for(int t=0;t < asset.duration.value;t++) { 
     CMTime thumbTime = CMTimeMake(t,asset.duration.timescale); 
     NSValue *v=[NSValue valueWithCMTime:thumbTime]; 
     [cmTimeArray addObject:v]; 
    } 
    NSLog(@"Array of time %@ count = %d",cmTimeArray, cmTimeArray.count); 
    //NSLog(@"Array count = %d",cmTimeArray.count); 
} 


- (void)generateCMTimesArrayOfFrames:(int)framesInterval UsingAsset:(AVURLAsset *)asset 
{ 
    int videoDuration = ceilf(((float)asset.duration.value/asset.duration.timescale)); 
    NSLog(@"Video duration %lld seconds timescale = %d",asset.duration.value,asset.duration.timescale); 
    if (cmTimeArray.count>0) { 
     [cmTimeArray removeAllObjects]; 
    } 
    //Generate limited frames present in video 
    for (int i = 0; i<videoDuration; i++) 
    { 
     int64_t tempInt = i; 
     CMTime tempCMTime = CMTimeMake(tempInt,1); 
     int32_t interval = framesInterval; 
     for (int j = 1; j<framesInterval+1; j++) 
     { 
      CMTime newCMtime = CMTimeMake(j,interval); 
      CMTime addition = CMTimeAdd(tempCMTime, newCMtime); 
      [cmTimeArray addObject:[NSValue valueWithCMTime:addition]]; 
     } 
    } 
    NSLog(@"Array of time %@ count = %d",cmTimeArray, cmTimeArray.count); 
    //NSLog(@"Array count = %d",cmTimeArray.count); 
} 


- (void)generateThumbnailsFromVideoURL:(AVURLAsset *)videoAsset 
{ 
    //Generate CMTimes Array of required frames 
    //1.Generate All Frames 
    //[self generateCMTimesArrayOfAllFramesUsingAsset:asset]; 

    //2.Generate specific frames per second 
    [self generateCMTimesArrayOfFrames:30 UsingAsset:videoAsset]; 

    __block int i = 0; 
    AVAssetImageGeneratorCompletionHandler handler = ^(CMTime requestedTime, CGImageRef im, CMTime actualTime, AVAssetImageGeneratorResult result, NSError *error){ 
    if (result == AVAssetImageGeneratorSucceeded) { 
     [framesArray addObject:[UIImage imageWithCGImage:im]]; 
    } 
    if (result == AVAssetImageGeneratorFailed) { 
     NSLog(@"Failed with error: %@ code %d", [error localizedDescription],error.code); 
    } 
    if (result == AVAssetImageGeneratorCancelled) { 
     NSLog(@"Canceled"); 
    } 

    i++; 
    imageIndex = i; 

    if(i == cmTimeArray.count) { 
     //Thumbnail generation completed 
    } 
}; 

    // Launching the process... 
    self.generator = [[AVAssetImageGenerator alloc] initWithAsset:videoAsset]; 
    self.generator.apertureMode = AVAssetImageGeneratorApertureModeCleanAperture; 
    self.generator.appliesPreferredTrackTransform=TRUE; 
    self.generator.requestedTimeToleranceBefore = kCMTimeZero; 
    self.generator.requestedTimeToleranceAfter = kCMTimeZero; 
    self.generator.maximumSize = CGSizeMake(40, 40); 
    [self.generator generateCGImagesAsynchronouslyForTimes:cmTimeArray completionHandler:handler]; 
} 
Смежные вопросы