2010-11-28 13 views
16

Ich spiele ein Video mit AVPlayer. Es funktioniert gut.Erhalte UIImage vom CALayer an den AVPlayer angehängt (Frame aus Video abspielen)

Jetzt möchte ich eine UIImage aus dem Video spielen (wenn ich einen Knopf für den Moment drücken).

An meine angeschlossen ist eine CALayer, die verwendet wird, um Video auf meinem UIView anzuzeigen. Meine Idee ist es, eine UIImage von CALayer während Video zu bekommen.

Ich tue dies mit dem Code von einer anderen Frage:

UIImage from CALayer - iPhone SDK

jedoch meine UIImage leer. Die Auflösung ist gut, aber es ist aber völlig weiß !!!

Es scheint, dass Video den Inhalt meiner CALayer nicht schreibt.

Jemand kann mir helfen? Dank

+2

könnten wir den Code sehen, der die Methode zum Erstellen des Bildes aufruft? –

Antwort

1

versuchen, das Bild aus der Videodatei zu bestimmten Instanz mit dem AVAssetImageGenerator zu bekommen:

 
    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

Ich konnte nicht treffen Lösung erhalten, für mich zu arbeiten, aber es hat mich in der richtigen Richtung zu denken .

Unten ist der Code, den ich in meinem Projekt verwendet habe. Die Methode screenshotFromPlayer:maximumSize: akzeptiert eine Instanz einer , von der ein Screenshot erstellt werden kann, und eine CGSize, die die maximale Größe des zurückgegebenen Bildes darstellt.

- (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; 
} 

Man beachte auch, dass man könnte das Verfahren generateCGImagesAsynchronouslyForTimes:completionHandler: anstelle von copyCGImageAtTime:actualTime:error: (auf der Instanz von AVAssetImageGenerator) verwenden, um die Bilderzeugung asynchron auszuführen.

Dieses Codebeispiel erstellt einen Screenshot unter der , aber jederzeit könnte stattdessen verwendet werden.

+2

Ich weiß, das ist super alt, aber für jeden, der jetzt darauf stößt, stellen Sie sicher, dass Sie tatsächlich eine CGImageRef vor der Veröffentlichung haben. Wenn nicht, was definitiv passieren kann, stürzt die App ab. –

8

Der Code, um Bild von AVplayer zu bekommen.

- (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]; 
} 

gesetzt [imageGenerator setRequestedTimeToleranceBefore:kCMTimeZero] und [imageGenerator setRequestedTimeToleranceAfter:kCMTimeZero], wenn Sie die genaue Zeit benötigen.