2010-11-28 11 views
16

私はAVPlayerでビデオを再生します。それは大丈夫です。AVPlayerに添付されたCALayerからUIImageを取得する(ビデオ再生からフレームを抽出する)

今、私はビデオを再生したいときに(私が一瞬ボタンを押したときに)UIImageを取得したいと思います。

AVPlayerには、UIViewにビデオを表示するために使用されるCALayerがあります。 私の考えは、ビデオが再生中にCALayerからUIImageを取得することです。

は、私は別の質問からのコードでこれを行う:

UIImage from CALayer - iPhone SDK

しかし私UIImageは空です。解像度は良いですが、完全に白です!!!

ビデオは私のCALayerの内容を書いていないようです。

誰かが私を助けることができますか? おかげ

+2

イメージを作成するメソッドを呼び出すコードを確認できますか? –

答えて

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

注また、1つの非同期画像生成を実行する(AVAssetImageGeneratorのインスタンスに)代わりcopyCGImageAtTime:actualTime:error:方法generateCGImagesAsynchronouslyForTimes:completionHandler:を使用することができます。

このコードサンプルでは、​​のcurrentTimeにスクリーンショットが生成されていますが、いつでも代わりに使用できます。

+2

私はこれが超古かったと知っていますが、今のところこれを見ている人にとっては、リリース前に実際にCGImageRefがあることを確認してください。あなたがしない場合、間違いなく起こる可能性があり、アプリはクラッシュします。 –

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]を設定します。

関連する問題