2011-05-11 13 views
18

Tengo una aplicación que estoy desarrollando para el iPhone. Lo que hace es capturar el video de la cámara y almacena el archivo de video en el sistema de archivos.Creación de miniaturas para video en iOS

Necesito crear una imagen en miniatura de este archivo de video antes de guardar la imagen en el sistema de archivos. Mi motivo es mostrar una lista de miniaturas del video creado para que el usuario pueda seleccionar una miniatura específica para reproducir el archivo deseado.

Podría alguien asesorarme sobre cómo puedo crear una imagen en miniatura de un archivo de video que ha sido capturado por la cámara.

Además, ¿me puede avisar si puedo crear una miniatura de un archivo de video existente con iOS SDK?

+0

posible duplicado de [Cómo tomar una captura de pantalla mediante programación] (http://stackoverflow.com/questions/2200736/how-to-take-a-screenshot-programmatically) –

+0

realidad estaba refiriendo a la generación de una imagen en miniatura de un archivo de video en IOS y no toma una captura de pantalla de forma programática. Para tomar una captura de pantalla, uno debería reproducir el archivo, pero en mi caso no es necesario reproducir el archivo. –

Respuesta

17

Prueba esto (que en realidad no muestran el reproductor de películas):

+ (UIImage *)imageFromMovie:(NSURL *)movieURL atTime:(NSTimeInterval)time { 
    // set up the movie player 
    MPMoviePlayerController *mp = [[MPMoviePlayerController alloc] 
    initWithContentURL:movieURL]; 
    mp.shouldAutoplay = NO; 
    mp.initialPlaybackTime = time; 
    mp.currentPlaybackTime = time; 
    // get the thumbnail 
    UIImage *thumbnail = [mp thumbnailImageAtTime:time 
          timeOption:MPMovieTimeOptionNearestKeyFrame]; 
    // clean up the movie player 
    [mp stop]; 
    [mp release]; 
    return(thumbnail); 
} 

Se supone que es una llamada sincrónica, por lo que podría bloquear el hilo principal algunos, pero parece estar funcionando bastante fácil conseguir cuando uso un tiempo al comienzo de la película. Si haces esto mucho, puedes agregarlo como una categoría en UIImage, que es lo que hice.

Veo por su pregunta que desea hacer esto antes de guardar la película, y supongo que podría no funcionar sin una url de archivo. Sin embargo, si está utilizando UIImagePickerController para la captura de la cámara, puede pasar esta función a la URL devuelta en el diccionario de información de imagePickerController: didFinishPickingMediaWithInfo: con la clave UIImagePickerControllerMediaURL.

+0

Este ejemplo debería ayudarme a lograr lo que requiero ... –

+3

thumbnailImageAtTime: timeOption: está DEPRECADO en iOS 7 – dusty

31

Una mejor solución en realidad es utilizar el marco AVFoundation para hacer esto. Se salta la necesidad de construir un MPMoviePlayerController que causa el problema de que el Iris de la cámara permanece cerrado si se usa junto con el UIImagePickerController (al menos eso es lo que experimenté).

El código que utilizo:

+ (UIImage *)thumbnailFromVideoAtURL:(NSURL *)contentURL { 
    UIImage *theImage = nil; 
    AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:contentURL options:nil]; 
    AVAssetImageGenerator *generator = [[AVAssetImageGenerator alloc] initWithAsset:asset]; 
    generator.appliesPreferredTrackTransform = YES; 
    NSError *err = NULL; 
    CMTime time = CMTimeMake(1, 60); 
    CGImageRef imgRef = [generator copyCGImageAtTime:time actualTime:NULL error:&err]; 

    theImage = [[[UIImage alloc] initWithCGImage:imgRef] autorelease]; 

    CGImageRelease(imgRef); 
    [asset release]; 
    [generator release]; 

    return theImage; 
} 
+0

Miniatura al final, AVPlayerItem * playerItem = [AVPlayerItem playerItemWithAsset: asset]; CM Duración del tiempo = playerItem.duración; – Underdog

+0

@Underdog No necesita un 'AVPlayerItem' para eso; simplemente recupere la duración de 'AVAsset' directamente. –

3

muy sencilla a probar esto ...

Paso 1: Importación cabecera #import <MediaPlayer/MediaPlayer.h>

Paso 2: Obtener ruta URL

NSURL *videoURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"Sample" ofType:@"m4v"]]; 

Paso 3: Finalmente obtener miniatura

- (UIImage *)VideoThumbNail:(NSURL *)videoURL 
{ 
    MPMoviePlayerController *player = [[MPMoviePlayerController alloc] initWithContentURL:videoURL]; 
    UIImage *thumbnail = [player thumbnailImageAtTime:52.0 timeOption:MPMovieTimeOptionNearestKeyFrame]; 
    [player stop]; 
    return thumbnail; 
} 
+1

thumbnailImageAtTime: timeOption: está DEPRECADO en iOS 7 – dusty

+0

este método está en desuso en ios 7 –

0

Prueba esto:

generate.requestedTimeToleranceBefore = kCMTimeZero; 
generate.requestedTimeToleranceAfter = kCMTimeZero; 

necesita añadido para conseguir marco correcto.

0

Código de solución que utiliza AVFoundation framework y Swift 3.0 (código comentado no es necesario y se discute a continuación el código - que tiene que decidir si lo necesita o no):

import AVFoundation 

func generateThumbnailForVideo(at url: URL) -> UIImage? { 
    let kPreferredTimescale: Int32 = 1000 
    let asset = AVURLAsset(url: url) 
    let generator = AVAssetImageGenerator(asset: asset) 
    generator.appliesPreferredTrackTransform = true 
    //generator.requestedTimeToleranceBefore = kCMTimeZero 
    //generator.requestedTimeToleranceAfter = kCMTimeZero 
    //generator.maximumSize = CGSize(width: 100, height: 100) 

    var actualTime: CMTime = CMTime(seconds: 0, preferredTimescale: kPreferredTimescale) 
    //generates thumbnail at first second of the video 
    let cgImage = try? generator.copyCGImage(at: CMTime(seconds: 1, preferredTimescale: kPreferredTimescale), actualTime: &actualTime) 
    return cgImage.flatMap() { return UIImage(cgImage: $0, scale: UIScreen.main.scale, orientation: .up) } 
} 

Tenga en cuenta que usted puede considerar la ejecución de este código en subproceso de fondo como la creación de miniaturas puede ser una operación potencialmente costosa.

También, por favor, eche un vistazo a algunas de las propiedades de AVAssetImageGenerator clase:

  1. requestedTimeToleranceBefore (Apple's documentation):

La longitud máxima de tiempo antes de una hora solicitada por el cual una la imagen puede ser generada.

El valor predeterminado es kCMTimePositiveInfinity.

Establezca los valores de requestedTimeToleranceBefore y requestTimeToleranceDespués de kCMTimeZero para solicitar la generación de imágenes con precisión de cuadro; esto puede incurrir en un retraso de decodificación adicional.

  1. requestedTimeToleranceAfter (Apple's documentation):

La longitud máxima de tiempo después de un tiempo solicitado por el cual se puede generar una imagen.

El valor predeterminado es kCMTimePositiveInfinity.

Establezca los valores de requestedTimeToleranceBefore y requestTimeToleranceDespués de kCMTimeZero para solicitar la generación de imágenes con precisión de cuadro; esto puede incurrir en un retraso de decodificación adicional.

  1. maximumSize (Apple's documentation):

especifica las dimensiones máximas de la imagen generada.

El valor predeterminado es CGSizeZero, que especifica las dimensiones sin escalar del activo.

AVAssetImageGenerator escala las imágenes de forma que quepan dentro del cuadro delimitador definido. Las imágenes nunca se amplían. La relación de aspecto de la imagen escalada se define mediante la propiedad apertureMode.

Cuestiones relacionadas