2010-11-28 11 views
16

Reproduzco un video con AVPlayer. Funciona bienObtener UIImage del CALayer conectado a AVPlayer (extraer fotograma de reproducción de video)

Ahora quiero obtener un UIImage de la reproducción de video (cuando presiono un botón por el momento).

Adjunto a mi AVPlayer hay un CALayer que se utiliza para mostrar video en mi UIView. Mi idea es obtener UIImage desde CALayer durante la reproducción del video.

Puedo hacer esto con código de otra pregunta: ¿

UIImage from CALayer - iPhone SDK

Sin embargo, mi UIImage está vacía. ¡La resolución es buena pero es completamente blanca!

Parece que el video no escribe el contenido de mi CALayer.

¿Alguien me puede ayudar? Gracias

+2

¿Podríamos ver el código que invoca el método para crear la imagen? –

Respuesta

1

intento para obtener la imagen del archivo de vídeo a instancia especificada mediante el AVAssetImageGenerator:

 
    AVURLAsset *asset=[[AVURLAsset alloc] initWithURL:[NSURL fileURLWithPath:[info objectForKey:@"UIImagePickerControllerReferenceURL"]] options:nil]; 
    AVAssetImageGenerator *generator = [[AVAssetImageGenerator alloc] initWithAsset:asset]; 
    generator.appliesPreferredTrackTransform=TRUE; 
    [asset release]; 
    CMTime thumbTime = CMTimeMakeWithSeconds(0,30); 
    AVAssetImageGeneratorCompletionHandler handler = ^(CMTime requestedTime, CGImageRef im, CMTime actualTime, AVAssetImageGeneratorResult result, NSError *error){ 
    if (result != AVAssetImageGeneratorSucceeded) { 

    } 
    UIImage *thumbImg = [[UIImage imageWithCGImage:im] retain]; 
    [generator release]; 
8

no pude conseguir la solución de reunirse para trabajar para mí, pero me hizo pensar en la dirección correcta .

A continuación se muestra el código que terminé usando en mi proyecto. El método screenshotFromPlayer:maximumSize: acepta una instancia de AVPlayer para tomar una captura de pantalla y CGSize que será el tamaño máximo de la imagen devuelta.

- (UIImage *)screenshotFromPlayer:(AVPlayer *)player maximumSize:(CGSize)maxSize { 

    CMTime actualTime; 
    NSError *error; 

    AVAssetImageGenerator *generator = [[AVAssetImageGenerator alloc] initWithAsset:player.currentItem.asset]; 

    // Setting a maximum size is not necessary for this code to 
    // successfully get a screenshot, but it was useful for my project. 
    generator.maximumSize = maxSize; 

    CGImageRef cgIm = [generator copyCGImageAtTime:player.currentTime 
             actualTime:&actualTime 
              error:&error]; 
    UIImage *image = [UIImage imageWithCGImage:cgIm]; 
    CFRelease(cgIm); 

    if (nil != error) { 
     NSLog(@"Error making screenshot: %@", [error localizedDescription]); 
     NSLog(@"Actual screenshot time: %f Requested screenshot time: %f", CMTimeGetSeconds(actualTime), 
      CMTimeGetSeconds(self.recordPlayer.currentTime)); 
     return nil; 
    } 

    return image; 
} 

Nótese también que se podría utilizar el método generateCGImagesAsynchronouslyForTimes:completionHandler: en lugar de copyCGImageAtTime:actualTime:error: (en la instancia de AVAssetImageGenerator) para llevar a cabo la generación de la imagen de forma asincrónica.

Este ejemplo de código genera una captura de pantalla en AVPlayer 's currentTime, pero cualquier momento podría utilizarse en su lugar.

+2

Sé que esto es muy viejo, pero para cualquiera que se encuentre con esto ahora, asegúrese de tener un CGImageRef antes de lanzarlo. Si no lo haces, lo que definitivamente puede suceder, la aplicación se bloqueará. –

8

El código para obtener la imagen de avplayer.

- (UIImage *)currentItemScreenShot 
{ 
    AVPlayer *abovePlayer = [abovePlayerView player]; 
    CMTime time = [[abovePlayer currentItem] currentTime]; 
    AVAsset *asset = [[[abovePlayerView player] currentItem] asset]; 
    AVAssetImageGenerator *imageGenerator = [[AVAssetImageGenerator alloc] initWithAsset:asset]; 
    if ([imageGenerator respondsToSelector:@selector(setRequestedTimeToleranceBefore:)] && [imageGenerator respondsToSelector:@selector(setRequestedTimeToleranceAfter:)]) { 
     [imageGenerator setRequestedTimeToleranceBefore:kCMTimeZero]; 
     [imageGenerator setRequestedTimeToleranceAfter:kCMTimeZero]; 
    } 
    CGImageRef imgRef = [imageGenerator copyCGImageAtTime:time 
              actualTime:NULL 
               error:NULL]; 
    if (imgRef == nil) { 
     if ([imageGenerator respondsToSelector:@selector(setRequestedTimeToleranceBefore:)] && [imageGenerator respondsToSelector:@selector(setRequestedTimeToleranceAfter:)]) { 
      [imageGenerator setRequestedTimeToleranceBefore:kCMTimePositiveInfinity]; 
      [imageGenerator setRequestedTimeToleranceAfter:kCMTimePositiveInfinity]; 
     } 
     imgRef = [imageGenerator copyCGImageAtTime:time actualTime:NULL error:NULL]; 
    } 
    UIImage *image = [[UIImage alloc] initWithCGImage:imgRef]; 
    CGImageRelease(imgRef); 
    [imageGenerator release]; 

    return [image autorelease]; 
} 

conjunto [imageGenerator setRequestedTimeToleranceBefore:kCMTimeZero] y [imageGenerator setRequestedTimeToleranceAfter:kCMTimeZero] si necesita tiempo preciso.

Cuestiones relacionadas