Получить UIImage из CALayer, подключенного к AVPlayer (извлечь кадр из видеоигра)
Я воспроизвожу видео с AVPlayer. Он работает нормально.
Теперь я хочу получить UIImage
от воспроизведения видео (когда я нажимаю кнопку на данный момент).
К моему AVPlayer
прилагается CALayer
, который используется для отображения видео на моем UIView
.
Моя идея - получить UIImage
от CALayer
во время воспроизведения видео.
Я делаю это с кодом из другого вопроса:
UIImage из CALayer - iPhone SDK
Однако мой UIImage
пуст. Разрешение хорошее, но оно полностью белое.
Кажется, что видео не записывает содержимое моего CALayer
.
Кто-нибудь может мне помочь?
Благодаря
Ответы
Ответ 1
Я не мог заставить решение Meet работать для меня, но это заставило меня думать в правильном направлении.
Ниже приведен код, который я использовал в своем проекте. Метод 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;
}
Обратите также внимание, что для выполнения генерации изображения асинхронно можно использовать метод generateCGImagesAsynchronouslyForTimes:completionHandler:
вместо copyCGImageAtTime:actualTime:error:
(в экземпляре AVAssetImageGenerator
).
Этот образец кода генерирует скриншот на AVPlayer
currentTime
, но в любое время его можно использовать.
Ответ 2
Код для получения изображения из 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]
, если вам нужно точное время.
Ответ 3
Попробуйте получить изображение из видеофайла в указанном экземпляре с помощью 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];