Lo siento por mi inglés)
Buscando información acerca de la lectura de los fotogramas de un vídeo con el iPhone me encontré con este proyecto, http://www.codza.com/extracting-frames-from-movies-on-iphone/comment-page-1#comment-1116, pero también he leído en alguna parte que usted puede utilizar AVFoundation para capturar fotogramas de un vídeo para un mejor rendimiento..

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

Alguna idea?

Gracias por leer

InformationsquelleAutor matiasfh | 2010-11-16

5 Comentarios

  1. 37

    Usted está hablando sobre el uso de las llamadas para la generación de lo que Apple llama imágenes en miniatura de videos en momentos específicos.

    Para un MPMoviePlayerController (lo que iOS utiliza para contener un vídeo de un archivo o de otra fuente), hay dos comandos para hacer esto. La primera genera una sola miniatura (imagen) de una película en un punto específico en el tiempo, y la segunda genera un conjunto de miniaturas para un intervalo de tiempo.

    Este ejemplo se obtiene una imagen en 10 segundos en 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 este realiza de forma sincrónica – es decir, el usuario estará obligado a esperar mientras te pones en la captura de pantalla.

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

    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 desencadenará una notificación de tipo MPMoviePlayerThumbnailImageRequestDidFinishNotification cada vez que una nueva imagen se genera. Puede configurar un observador de la supervisión de este proceso y de la imagen – voy a salir a trabajar un poco en su propio!

    • Gracias!!.. es una buena idea.. voy a resolver esto usando ffmpeg, pero yo wan algo que no nativas para iOS SDK .. voy a probar tu idea
    • acerca de la primera parte, ¿tiene usted alguna idea de cómo hacerlo de forma asincrónica?
    • usted no sería la primera forma si usted necesita de forma asincrónica… si sólo desea una imagen, sino asincrónico, utilizar el segundo método con una matriz de una sola vez 🙂
    • El problema con este método es que se bloquea si el fondo de la aplicación.
    • MPMoviePlayerThumbnailImageRequestdidfinishnotification no funciona
    • Es este método de extracción es creíble, quiero decir, ¿realmente funciona bien? La verdad es que puede implementar la misma funcionalidad mediante iFrameExtractor github.com/lajos/iFrameExtractor .Pero yo no quiero ir a través de ese método y el pensamiento de la aplicación de este método… Así que por favor dame la dirección correcta !! Gracias de antemano
    • Yo también enfrentan el mismo problema que MPMoviePlayerThumbnailImageRequestdidfinishnotification no es despedido

  2. 5

    Swift 2 código marcos 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
        }
    }
  3. 1

    En Swift 4 esto funcionó para mí, con algunas modificaciones, principalmente en el cambio de la «a» parámetro de imageGenerator.copyCGImage a un CMTime tipo:

    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

  4. 1

    Aquí está el código para obtener FPS imágenes de vídeo

    1) Importar

    #import <Photos/Photos.h>

    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.");
            }
        }];
    }

Dejar respuesta

Please enter your comment!
Please enter your name here