iPhone leyó UIimage (fotogtwigs) de video con AVFoundation

Lo siento por mi inglés) Buscando información sobre marcos de lectura de un video con iPhone encontré este proyecto, http://www.codza.com/extracting-frames-from-movies-on-iphone/comment-page-1#comment -1116 , pero también leí en alguna parte que puede usar AVFoundation para capturar fotogtwigs de un video para un mejor rendimiento.

Pero no puedo encontrar información de cómo puedo hacer eso …

¿Alguna idea?

Gracias por leer

Está hablando de usar las llamadas para generar lo que Apple llama imágenes en miniatura de videos en momentos específicos.

Para un MPMoviePlayerController (lo que iOS usa para guardar un video de un archivo u otra fuente), hay dos comandos para hacer esto. El primero genera una miniatura (imagen) única de una película en un punto específico en el tiempo, y el segundo genera un conjunto de miniaturas para un rango de tiempo.

Este ejemplo obtiene una imagen a los 10 segundos de un clip de película, myMovie.mp4 :

MPMoviePlayerController *movie = [[MPMoviePlayerController alloc] initWithContentURL:[NSURL URLWithString:@"myMovie.mp4"]]; UIImage *singleFrameImage = [movie thumbnailImageAtTime:10 timeOption:MPMovieTimeOptionExact]; 

Tenga en cuenta que esto se realiza de forma síncrona, es decir, el usuario se verá obligado a esperar mientras obtiene la captura de pantalla.

La otra opción es obtener una serie de imágenes de una película, de una serie de veces:

 MPMoviePlayerController *movie = [[MPMoviePlayerController alloc] initWithContentURL [NSURL URLWithString:@"myMovie.mp4"]]; NSNumber time1 = 10; NSNumber time2 = 11; NSNumber time3 = 12; NSArray *times = [NSArray arrayWithObjects:time1,time2,time3,nil]; [movie requestThumbnailImagesAtTimes:times timeOption:MPMovieTimeOptionExact]; 

Esta segunda forma activará una notificación de tipo MPMoviePlayerThumbnailImageRequestDidFinishNotification cada vez que se genere una nueva imagen. Puede configurar un observador para que lo supervise y procese la imagen; ¡lo dejaré trabajar por su cuenta!

También puede probar AVAssetImageGenerator , específicamente generateCGImagesAsynchronouslyForTimes: completionHandler .

Esta respuesta SO tiene un buen código de ejemplo.

Código de Swift 2 para tomar fotogtwigs con AVAssetImageGenerator:

 func previewImageForLocalVideo(url:NSURL) -> UIImage? { let asset = AVAsset(URL: url) let imageGenerator = AVAssetImageGenerator(asset: asset) imageGenerator.appliesPreferredTrackTransform = true var time = asset.duration //If possible - take not the first frame (it could be completely black or white on camara's videos) time.value = min(time.value, 2) do { let imageRef = try imageGenerator.copyCGImageAtTime(time, actualTime: nil) return UIImage(CGImage: imageRef) } catch let error as NSError { print("Image generation failed with error \(error)") return nil } } 

En Swift 4 esto funcionó para mí con algunas modificaciones, principalmente cambiando el parámetro “at” de imageGenerator.copyCGImage a un tipo CMTime:

 func showFrame(from file:String) { let file = file.components(separatedBy: ".") guard let path = Bundle.main.path(forResource: file[0], ofType:file[1]) else { debugPrint( "\(file.joined(separator: ".")) not found") return } let url = URL(fileURLWithPath: path) let image = previewImageForLocalVideo(url: url) let imgView = UIImageView(image: image) view.addSubview(imgView) } func previewImageForLocalVideo(url:URL) -> UIImage? { let asset = AVAsset(url: url) let imageGenerator = AVAssetImageGenerator(asset: asset) imageGenerator.appliesPreferredTrackTransform = true let tVal = NSValue(time: CMTimeMake(12, 1)) as! CMTime do { let imageRef = try imageGenerator.copyCGImage(at: tVal, actualTime: nil) return UIImage(cgImage: imageRef) } catch let error as NSError { print("Image generation failed with error \(error)") return nil } } override func viewDidLoad() { super.viewDidLoad() showFrame(from:"video.mp4") } 

Fuente

Aquí hay un código para obtener imágenes FPS del video

1) Importar

 #import  

2) en viewDidLoad

  videoUrl = [NSURL fileURLWithPath:[[NSBundle mainBundle]pathForResource:@"VfE_html5" ofType:@"mp4"]]; [self createImage:5]; // 5 is frame per second (FPS) you can change FPS as per your requirement. 

3) Funciones

 -(void)createImage:(int)withFPS { AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:videoUrl options:nil]; AVAssetImageGenerator *generator = [[AVAssetImageGenerator alloc] initWithAsset:asset]; generator.requestedTimeToleranceAfter = kCMTimeZero; generator.requestedTimeToleranceBefore = kCMTimeZero; for (Float64 i = 0; i < CMTimeGetSeconds(asset.duration) * withFPS ; i++){ @autoreleasepool { CMTime time = CMTimeMake(i, withFPS); NSError *err; CMTime actualTime; CGImageRef image = [generator copyCGImageAtTime:time actualTime:&actualTime error:&err]; UIImage *generatedImage = [[UIImage alloc] initWithCGImage:image]; [self savePhotoToAlbum: generatedImage]; // Saves the image on document directory and not memory CGImageRelease(image); } } } -(void)savePhotoToAlbum:(UIImage*)imageToSave { [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{ PHAssetChangeRequest *changeRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:imageToSave]; } completionHandler:^(BOOL success, NSError *error) { if (success) { NSLog(@"sucess."); } else { NSLog(@"fail."); } }]; }