2010-11-28 24 views
16

AVPlayer ile video oynarım. Tamam çalışıyor.AVPlayer'a bağlı CALayer'den UIImage'ı edinin (video oynatımından çerçeve çıkar)

Şimdi video oynatımından (şu an için bir düğmeye bastığımda) bir UIImage almak istiyorum.

AVPlayer Ekimde, UIView sayfamda videoyu görüntülemek için kullanılan CALayer bulunmaktadır. Fikrim, video oynatılırken CALayer numaralı telefondan UIImage almaktır.

başka bir soru kod ile bunu:

UIImage from CALayer - iPhone SDK

Ancak benim UIImage boş. Çözünürlük iyidir, ancak tam beyazdır !!!

Görünüşe göre video benim CALayer'un içeriğini yazmıyor.

Birisi bana yardımcı olabilir? Teşekkür

+2

Görüntüyü oluşturma yöntemini çağıran kodu görebilir miyiz? –

cevap

1

deneyin AVAssetImageGenerator kullanılarak belirtilen örneğine video dosyasından görüntü elde etmek için:

 
    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

benim için çalışmak Meet çözüm alamadım, ama doğru yönde düşünmeye başladım .

Projemde kullanmakta olduğum kod aşağıdadır. screenshotFromPlayer:maximumSize: yöntemi, bir ekran görüntüsünün alınacağı bir AVPlayer örneğini ve döndürülen görüntünün maksimum boyutu olacak bir CGSize kabul eder.

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

Not Ayrıca bir senkronize olmayan görüntü oluşumunu gerçekleştirmek için (AVAssetImageGenerator örneğinde) yöntemini generateCGImagesAsynchronouslyForTimes:completionHandler: yerine copyCGImageAtTime:actualTime:error: kullanabilir.

Bu kod örneği, AVPlayer ürününün currentTime numaralı telefonunda bir ekran görüntüsü oluşturur, ancak bunun yerine herhangi bir zaman kullanılabilir.

+2

Bunun süper yaşlı olduğunu biliyorum, ancak şu anda karşımıza çıkan herkes için, bir CGImageRef'i yayınlamadan önce mutlaka aldığınızdan emin olun. Yapmazsanız, kesinlikle olabilir, uygulama çökecektir. –

8

Avplayer'dan görüntü alma kodu. Eğer hassas zaman gerekirse

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

[imageGenerator setRequestedTimeToleranceBefore:kCMTimeZero] ve [imageGenerator setRequestedTimeToleranceAfter:kCMTimeZero] ayarlayın.