2010-11-28 16 views
16

나는 AVPlayer로 비디오를 재생합니다. 괜찮아.AVPlayer에 연결된 CALayer에서 UIImage 가져 오기 (비디오 재생에서 프레임 추출)

이제 동영상 재생 중에 (내가 잠시 버튼을 누르면) UIImage을 얻고 싶습니다.

AVPlayer에 첨부 된 UIView에 비디오를 표시하는 데 사용되는 CALayer이 있습니다. 내 생각은 비디오가 재생되는 동안 을 CALayer에서 얻는 것입니다.

나는 또 다른 질문의 코드와 함께이 작업을 수행 :

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

참고 또한 하나의 비동기 영상 생성을 수행하는 (AVAssetImageGenerator의 인스턴스)에있어서 generateCGImagesAsynchronouslyForTimes:completionHandler: 대신 copyCGImageAtTime:actualTime:error:을 사용할 수있다.

이 코드 샘플은 의 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 setRequestedTimeToleranceBefore:kCMTimeZero][imageGenerator setRequestedTimeToleranceAfter:kCMTimeZero]을 설정합니다.