2009-10-05 17 views
12

Estoy tratando de obtener el primer fotograma del video seleccionado en un UIImagePickerController para mostrar en un UIImageView, pero no sé si es posible. Si es así, ¿cómo lo haría?¿Tomar el primer fotograma de un video de UIImagePickerController?

+0

pregunta similar http://stackoverflow.com/questions/1347562/getting-thumbnail-from-a-video-url-or-data-in-iphone-sdk –

Respuesta

27

Puede hacerlo de dos maneras. La primera forma es utilizar el MPMoviePlayerController para agarrar la miniatura:

MPMoviePlayerController *moviePlayer = [[MPMoviePlayerController alloc] 
             initWithContentURL:videoURL]; 
moviePlayer.shouldAutoplay = NO; 
UIImage *thumbnail = [moviePlayer thumbnailImageAtTime:time 
        timeOption:MPMovieTimeOptionNearestKeyFrame]; 

Esto funciona, pero MPMoviePlayerController no es un objeto especialmente ligero y no particularmente agarrar rápido miniaturas.

La forma preferida es utilizar el nuevo AVAssetImageGenerator en AVFoundation. Esto es rápido, ligero y más flexible que en el pasado. Aquí hay un método de ayuda que devolverá una imagen autorrebectada del video.


+ (UIImage *)thumbnailImageForVideo:(NSURL *)videoURL 
          atTime:(NSTimeInterval)time 
{ 

    AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:videoURL options:nil]; 
    NSParameterAssert(asset); 
    AVAssetImageGenerator *assetIG = 
       [[AVAssetImageGenerator alloc] initWithAsset:asset]; 
    assetIG.appliesPreferredTrackTransform = YES; 
    assetIG.apertureMode = AVAssetImageGeneratorApertureModeEncodedPixels; 

    CGImageRef thumbnailImageRef = NULL; 
    CFTimeInterval thumbnailImageTime = time; 
    NSError *igError = nil; 
    thumbnailImageRef = 
      [assetIG copyCGImageAtTime:CMTimeMake(thumbnailImageTime, 60) 
          actualTime:NULL 
            error:&igError]; 

    if (!thumbnailImageRef) 
     NSLog(@"thumbnailImageGenerationError %@", igError); 

    UIImage *thumbnailImage = thumbnailImageRef 
          ? [[UIImage alloc] initWithCGImage:thumbnailImageRef] 
          : nil; 

    return thumbnailImage; 
} 

uso asíncrono


- (void)thumbnailImageForVideo:(NSURL *)videoURL atTime:(NSTimeInterval)time completion:(void (^)(UIImage *)) completion 
{ 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ 

     AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:videoURL options:nil]; 
     NSParameterAssert(asset); 
     AVAssetImageGenerator *assetIG = 
     [[AVAssetImageGenerator alloc] initWithAsset:asset]; 
     assetIG.appliesPreferredTrackTransform = YES; 
     assetIG.apertureMode = AVAssetImageGeneratorApertureModeEncodedPixels; 

     CGImageRef thumbnailImageRef = NULL; 
     CFTimeInterval thumbnailImageTime = time; 
     NSError *igError = nil; 
     thumbnailImageRef = 
     [assetIG copyCGImageAtTime:CMTimeMake(thumbnailImageTime, 60) 
         actualTime:NULL 
          error:&igError]; 

     if (!thumbnailImageRef) 
      NSLog(@"thumbnailImageGenerationError %@", igError); 

     UIImage *thumbnailImage = thumbnailImageRef 
     ? [[UIImage alloc] initWithCGImage:thumbnailImageRef] 
     : nil; 

     dispatch_async(dispatch_get_main_queue(), ^{ 
      completion(thumbnailImage); 
     }); 
    }); 
} 
+1

También debe agregar el marco "Core Media" a su objetivo. –

+0

+1 Mi colega no pudo escribir algo como esto, pero gracias a ti ... –

+0

para otros que intenten usar esto: presta atención si el videoURL fue creado por fileURLWithPath o URLWithString (cuando tienes la ruta en NSString *) – user1105951

Cuestiones relacionadas