web-dev-qa-db-fra.com

thumbnailImageAtTime: maintenant obsolète - Quelle est l'alternative?

Jusqu'à la mise à jour iOS7, j'utilisais ...

UIImage *image = [moviePlayer thumbnailImageAtTime:1.0 timeOption:MPMovieTimeOptionNearestKeyFrame];

... avec un grand succès, afin que mon application puisse afficher un extrait de la vidéo que l'utilisateur vient de prendre.

Je comprends cette méthode, à partir de iOS 7 est maintenant obsolète et j'ai besoin d'une alternative. Je vois qu'il y a une méthode de

- (void)requestThumbnailImagesAtTimes:(NSArray *)playbackTimes timeOption:(MPMovieTimeOption)option

mais comment puis-je retourner l'image à partir de celle-ci afin de pouvoir la placer dans l'image du bouton videoReview?

Merci d'avance, Jim.

**** Question modifiée, après avoir essayé la méthode du centre de notification ***

J'ai utilisé le code suivant -

[moviePlayer requestThumbnailImagesAtTimes:times timeOption:MPMovieTimeOptionNearestKeyFrame];

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(MPMoviePlayerThumbnailImageRequestDidFinishNotification::) name:MPMoviePlayerThumbnailImageRequestDidFinishNotification object:moviePlayer];

J'ai créé les temps NSArray de deux objets NSNumber 1 et 2.

J'ai ensuite essayé de capturer la notification avec la méthode suivante

-(void)MPMoviePlayerThumbnailImageRequestDidFinishNotification: (NSDictionary*)info{

UIImage *image = [info objectForKey:MPMoviePlayerThumbnailImageKey];

Nous avons ensuite utilisé cette image miniature en tant qu'image de bouton en tant qu'aperçu ... mais cela n'a pas fonctionné.

Si vous voyez dans mon codage où je me suis trompé, votre aide serait à nouveau appréciée. À votre santé

22
Jim Tierney

Géré pour trouver un bon moyen d'utiliser AVAssetImageGenerator, veuillez consulter le code ci-dessous ...

AVURLAsset *asset1 = [[AVURLAsset alloc] initWithURL:partOneUrl options:nil];
AVAssetImageGenerator *generate1 = [[AVAssetImageGenerator alloc] initWithAsset:asset1];
generate1.appliesPreferredTrackTransform = YES;
NSError *err = NULL;
CMTime time = CMTimeMake(1, 2);
CGImageRef oneRef = [generate1 copyCGImageAtTime:time actualTime:NULL error:&err];
UIImage *one = [[UIImage alloc] initWithCGImage:oneRef];
[_firstImage setImage:one];
_firstImage.contentMode = UIViewContentModeScaleAspectFit;

Dans le fichier d'en-tête, veuillez importer

#import <AVFoundation/AVFoundation.h>

Cela fonctionne parfaitement et j'ai pu l'appeler depuis viewDidLoad, ce qui était plus rapide que d'appeler le obsolète thumbNailImageAtTime: depuis viewDidAppear.

J'espère que cela aide tous ceux qui ont eu le même problème.

41
Jim Tierney

La méthode requestThumbnailImagesAtTimes: timeOption: publiera une notification MPMoviePlayerThumbnailImageRequestDidFinishNotification lorsqu'une demande d'image est terminée. Votre code nécessitant la vignette doit vous abonner à cette notification à l'aide de NSNotificationCenter , et utiliser l'image lorsqu'il reçoit la notification.

5
Greg

La façon de le faire, du moins dans iOS7, consiste à utiliser des flotteurs pour votre temps

NSNumber *timeStamp = @1.f;
[moviePlayer requestThumbnailImagesAtTimes:timeStamp timeOption:MPMovieTimeOptionNearestKeyFrame];

J'espère que cela t'aides

2
nimeshdesai

Jeely fournit un bon travail de contournement, mais il nécessite une bibliothèque supplémentaire qui n'est pas nécessaire lorsque MPMoviePlayer fournit déjà des fonctions pour cette tâche. J'ai remarqué une erreur de syntaxe dans le code de l'affiche originale. Le gestionnaire de notification de vignettes attend un objet de type NSNotification et non un objet dictionnaire. Voici un exemple corrigé:

-(void)MPMoviePlayerThumbnailImageRequestDidFinishNotification: (NSNotification*)note
{
    NSDictionary * userInfo = [note userInfo];
    UIImage *image = (UIImage *)[userInfo objectForKey:MPMoviePlayerThumbnailImageKey];
    if(image!=NULL)
        [thumbView setImage:image];
}
2
Jonesy

Le problème est que vous devez spécifier des valeurs flottantes dans requestThumbnailImagesAtTimes.

Par exemple, ceci fonctionnera

[self.moviePlayer requestThumbnailImagesAtTimes:@[@14.f] timeOption:MPMovieTimeOptionNearestKeyFrame];

mais cela ne fonctionnera pas :

[self.moviePlayer requestThumbnailImagesAtTimes:@[@14] timeOption:MPMovieTimeOptionNearestKeyFrame];
2
sash

Je viens juste de chercher une solution à ce problème moi-même et votre question vous a été d'une grande aide. Votre code ci-dessus fonctionne avec un petit changement, a supprimé un colon ...

Changement

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(MPMoviePlayerThumbnailImageRequestDidFinishNotification::) name:MPMoviePlayerThumbnailImageRequestDidFinishNotification object:moviePlayer];

à

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(MPMoviePlayerThumbnailImageRequestDidFinishNotification:) name:MPMoviePlayerThumbnailImageRequestDidFinishNotification object:moviePlayer];

Cela a fonctionné bien. En outre, j'ai constaté que vous ne pouvez pas appeler une méthode sans l'aide de Notification Center si vous êtes déjà dans un sélecteur de notification. Quelque chose que j'ai essayé au début - j'ai essayé d'appeler requestThumbnailImagesAtTimes dans le sélecteur de notification pour MPMoviePlayerPlaybackDidFinishNotification - quelque chose qui ne fonctionnerait pas. Je pense que parce que la notification ne se déclenche pas.

0
Frippuz

Le code dans Swift 2.1 ressemblerait à ceci:

do{
    let asset1 =  AVURLAsset(URL: url)
    let generate1: AVAssetImageGenerator = AVAssetImageGenerator(asset: asset1)
    generate1.appliesPreferredTrackTransform = true

    let time: CMTime = CMTimeMake(3, 1)  //TO CATCH THE THIRD SECOND OF THE VIDEO
    let oneRef: CGImageRef = try generate1.copyCGImageAtTime(time, actualTime: nil)
    let resultImage = UIImage(CGImage: oneRef)
}
catch let error as NSError{
    print(error)
}
0
Carlos Perez Perez