2011-04-28 22 views
5

Cada vez que intento generar un fotograma de mi activo de video, se genera en un tiempo de 0.000 segundos. Puedo ver esto desde mi mensaje de registro. Lo bueno es que puedo obtener la imagen en el momento 0.000 .. para aparecer en un UIImageView llamado "myImageView". Pensé que el problema era que AVURLAssetPreferPreciseDurationAndTimingKey no se ha establecido, pero incluso después de que me di cuenta de cómo hacer eso, todavía no funciona ..No puedo obtener un CMTime preciso para generar imágenes fijas a partir de un video de 1.8 segundos

Aquí es lo que tengo ..

tiempo, Actualtime, y generar están declarados en el encabezamiento

NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"Documents/videoTest4.m4v"]]; 
//UISaveVideoAtPathToSavedPhotosAlbum(path, self, @selector(video:didFinishSavingWithError:contextInfo:), nil); 
NSURL *url = [NSURL fileURLWithPath:path]; 

NSDictionary *options = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:AVURLAssetPreferPreciseDurationAndTimingKey]; 
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:url options:options]; 

Float64 durationSeconds = CMTimeGetSeconds([asset duration]); 

generate = [[AVAssetImageGenerator alloc] initWithAsset:asset]; 
NSError *err = nil; 

time = CMTimeMake(600,600.0); 
CGImageRef imgRef = [generate copyCGImageAtTime:time actualTime:&actualTime error:&err]; 
UIImage *currentImg = [[UIImage alloc] initWithCGImage:imgRef]; 
myImageView.image = currentImg; 

NSLog(@"The total Video Duration is %f",durationSeconds); 
NSLog(@"The time I want my image is %f",CMTimeGetSeconds(time)); 
NSLog(@"The actual time my image was take was %f",CMTimeGetSeconds(actualTime)); 

Y mi consola lee ..

2011-04-28 18: 49: 59.062 VideoTesT [26553: 207] el vídeo Duración total es 1,880000

2011-04-28 18: 49: 59.064 VideoTesT [26553: 207] El tiempo Quiero que mi imagen es 1,000000

2011-04-28 18: 49: 59.064 VideoTesT [26553: 207] El tiempo real de mi la imagen era toma era 0,000000

..........................

Gracias chicos tanto de antemano .. :)

+1

Acabo de probar una segunda pinza 6 .. Cuando solicito imagen a los 2 segundos, sigo teniendo mi imagen a las 0.00 .. cuando solicito la imagen a 4 segundos, finalmente consigo una imagen en 5.003 segundos ! ¡Entonces mi código está funcionando, solo necesito mucha más precisión! – johntraver

Respuesta

22

Para resolver este sólo tiene que establecer requestedTimeToleranceBefore y requestedTimeToleranceAfter a kCMTimeZero para AVAssetImageGenerator.

AVAssetImageGenerator Class Reference

+3

¡Esta es la mejor sugerencia, al menos en mi opinión! – SlowTree

+1

De acuerdo. ¡Esto resolvió el problema! –

5

Anoche anoche tuve una Idea y, por supuesto, funcionó esta mañana. Básicamente, solo creo un nuevo activo de composición y luego creo un rango de tiempo que representa un fotograma para video a 24 fotogramas por segundo. Una vez que tengo estas composiciones creadas, solo tomo el primer fotograma de cada comp. Hago esto para cada fotograma y creo una matriz que contiene todos mis marcos. Esto es lo que hice ..

NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"Documents/videoTest4.m4v"]]; 
//UISaveVideoAtPathToSavedPhotosAlbum(path, self, @selector(video:didFinishSavingWithError:contextInfo:), nil); 
NSURL *url = [NSURL fileURLWithPath:path]; 

NSDictionary *options = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:AVURLAssetPreferPreciseDurationAndTimingKey]; 
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:url options:options]; 

Float64 durationFrames = CMTimeGetSeconds([asset duration]) * 24.0; 

AVMutableComposition *myComp = [AVMutableComposition composition]; 

AVMutableCompositionTrack *compositionVideoTrack = [myComp addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid]; 

NSError *error = nil; 
BOOL ok = NO; 

NSMutableArray* frameArray = [[NSMutableArray alloc] init]; 

generate = [[AVAssetImageGenerator alloc] initWithAsset:myComp]; 
NSError *err = nil; 

for (int i = 0; i < floor(durationFrames); i++) { 

    CMTime startTime = CMTimeMake(i, 24); 
    CMTime endTime = CMTimeMake(i+1, 24); 

    CMTimeRange myRange = CMTimeRangeMake(startTime, endTime); 

    AVAssetTrack *sourceVideoTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]; 
    ok = [compositionVideoTrack insertTimeRange:myRange ofTrack:sourceVideoTrack atTime:kCMTimeZero error:&error]; 
    if (!ok) { 
     // Deal with the error. 
    } 

    time = CMTimeMake(0,1); 
    CGImageRef imgRef = [generate copyCGImageAtTime:time actualTime:&actualTime error:&err]; 
    UIImage *currentImg = [[UIImage alloc] initWithCGImage:imgRef]; 
    [frameArray addObject:currentImg]; 

    [currentImg release]; 

} 

NSLog(@"This video is calculated at %f Frames..",durationFrames); 
NSLog(@"You made a total of %i Frames!!",[frameArray count]); 

lee la consola ..

2011-04-29 10: 42: 24.292 VideoTesT [29019: 207] Este video se calcula en 45.120000 Marcos ..

2011-04-29 10: 42: 24.293 videoTest [29019: 207] ¡¡Hiciste un total de 45 marcos !!

Cuestiones relacionadas