2010-11-28 68 views
16

我使用AVPlayer播放視頻。它工作正常。從附加到AVPlayer的CALayer獲取UIImage(從視頻播放提取幀)

現在我想從視頻播放中獲得UIImage(當我按下按鈕時)。

附加到我的AVPlayer有一個CALayer用於在我的UIView上顯示視頻。 我的想法是在視頻播放過程中從CALayer獲得UIImage

我做到這一點的代碼從另一個問題:

UIImage from CALayer - iPhone SDK

但是我UIImage是空的。該決議是好的,但它是全白的!

看來,視頻並沒有寫我的CALayer的內容。

有人可以幫助我嗎? 感謝

+2

我們能否看到調用該方法來創建圖像的代碼? – 2012-01-13 13:47:32

回答

1

嘗試使用AVAssetImageGenerator獲得從視頻文件中的圖像在指定的實例:

 
    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

我無法得到滿足的解決方案,爲我工作,但它讓我在正確的方向思考。

下面是我最終在我的項目中使用的代碼。方法screenshotFromPlayer:maximumSize:接受AVPlayer的一個實例以從中截取屏幕截圖,CGSize將返回圖像的最大尺寸。

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

還請注意,人們可以使用(上的AVAssetImageGenerator的實例)的方法generateCGImagesAsynchronouslyForTimes:completionHandler:代替copyCGImageAtTime:actualTime:error:異步地執行圖像生成。

此代碼示例在AVPlayercurrentTime處生成屏幕截圖,但可以使用任何時間代替。

+2

我知道這是超級老,但對於任何現在遇到此問題的人來說,確保您在發佈前確實擁有CGImageRef。如果你不這樣做,肯定會發生,應用程序將崩潰。 – 2016-11-20 07:31:06

8

從avplayer獲取圖片的代碼。

- (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 setRequestedTimeToleranceAfter:kCMTimeZero]如果你需要精確的時間。