iOS toma múltiples capturas de pantalla

Tengo un NSURL que contiene un video, y quiero grabar un fotogtwig de ese video diez veces por segundo. Y tengo un código que capturará una image de mi reproductor, pero tengo problemas para configurarlo para capturar 10 fotogtwigs por segundo. Estoy probando algo como esto, pero ¿está devolviendo el mismo marco inicial del video, el número correcto de veces? Esto es lo que tengo:

AVAsset *asset = [AVAsset assetWithURL:videoUrl]; CMTime vidLength = asset.duration; float seconds = CMTimeGetSeconds(vidLength); int frameCount = 0; for (float i = 0; i < seconds;) { AVAssetImageGenerator *imageGenerator = [[AVAssetImageGenerator alloc]initWithAsset:asset]; CMTime time = CMTimeMake(i, 10); CGImageRef imageRef = [imageGenerator copyCGImageAtTime:time actualTime:NULL error:NULL]; UIImage *thumbnail = [UIImage imageWithCGImage:imageRef]; CGImageRelease(imageRef); NSString* filename = [NSString stringWithFormat:@"Documents/frame_%d.png", frameCount]; NSString* pngPath = [NSHomeDirectory() stringByAppendingPathComponent:filename]; [UIImagePNGRepresentation(thumbnail) writeToFile: pngPath atomically: YES]; frameCount++; i = i + 0.1; } 

Pero en lugar de get el marco en el momento actual i del video, ¿acaban de get el marco inicial?

¿Cómo puedo get el marco del video 10 veces por segundo?

Gracias por la ayuda 🙂

Obtiene marco inicial porque está intentando crear CMTime con ayuda de valor flotante:

 CMTime time = CMTimeMake(i, 10); 

Como la function CMTimeMake toma el valor int64_t como primer parámetro, tu valor flotante se networkingondeará a int, y obtendrás un resultado incorrecto.

Permite cambiar su código un poco:

1) Al principio, debe encontrar el recuento total de cuadros que necesita get del video. Escribió que necesita 10 fotogtwigs por segundo, por lo que el código será:

 int requinetworkingFramesCount = seconds * 10; 

2) A continuación, necesita encontrar un valor que aumente su valor de CMTime en cada paso:

 int64_t step = vidLength.value / requinetworkingFramesCount; 

3) Y, por último, necesita establecer requestedTimeToleranceBefore y solicitarTimeToleranceAfter a kCMTimeZero, para get un marco en el momento preciso:

 imageGenerator.requestedTimeToleranceAfter = kCMTimeZero; imageGenerator.requestedTimeToleranceBefore = kCMTimeZero; 

Así es como se verá tu código:

 CMTime vidLength = asset.duration; float seconds = CMTimeGetSeconds(vidLength); int requinetworkingFramesCount = seconds * 10; int64_t step = vidLength.value / requinetworkingFramesCount; int value = 0; for (int i = 0; i < requinetworkingFramesCount; i++) { AVAssetImageGenerator *imageGenerator = [[AVAssetImageGenerator alloc]initWithAsset:asset]; imageGenerator.requestedTimeToleranceAfter = kCMTimeZero; imageGenerator.requestedTimeToleranceBefore = kCMTimeZero; CMTime time = CMTimeMake(value, vidLength.timescale); CGImageRef imageRef = [imageGenerator copyCGImageAtTime:time actualTime:NULL error:NULL]; UIImage *thumbnail = [UIImage imageWithCGImage:imageRef]; CGImageRelease(imageRef); NSString* filename = [NSString stringWithFormat:@"Documents/frame_%d.png", i]; NSString* pngPath = [NSHomeDirectory() stringByAppendingPathComponent:filename]; [UIImagePNGRepresentation(thumbnail) writeToFile: pngPath atomically: YES]; value += step; } 

Con CMTimeMake(A, B) almacena un número racional, una fracción exacta A / B segundos, y el primer parámetro de esta function toma valor int. Durante 20 segundos de video, capturará un cuadro con time ((int) 19.9) / 10 = 1.9 segundos en la última iteración de su ciclo. Utilice la function CMTimeMakeWithSeconds(i, NSEC_PER_SEC) para solucionar este problema de time.