У меня есть AVPlayerLayer (подкласс CALayer), и мне нужно войти в тип изображения, который может быть передан в QCRenderer (QCRenderer принимает NSImages и CIImages.) Я могу преобразовать CALayer в CGImageRef, и это в NSImage, но содержание всегда ясно.
Я сузил это до одной из двух причин:
- Я неправильно создаю NSImage.
- AVPlayer не рендерится на AVPlayerLayer.
Я не получаю никаких ошибок, и нашел некоторую документацию по конвертации CALayers. Кроме того, я добавил AVPlayerLayer в NSView, который остается пустым, поэтому я считаю, что проблема заключается в 2.
Я использую модифицированную версию AVPlayerDemo от AVPlayerDemoPlaybackViewController от Apple. Я превратил его в NSObject, так как я удалил весь код интерфейса из него.
Я создаю AVPlayerLayer в (void) prepareToPlayAsset: withKeys: метод при создании AVPlayer: (я только добавляю слой в NSView, чтобы проверить, работает ли он.)
if (![self player])
{
/* Get a new AVPlayer initialized to play the specified player item. */
[self setPlayer:[AVPlayer playerWithPlayerItem:self.mPlayerItem]];
/* Observe the AVPlayer "currentItem" property to find out when any
AVPlayer replaceCurrentItemWithPlayerItem: replacement will/did
occur.*/
[self.player addObserver:self
forKeyPath:kCurrentItemKey
options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew
context:AVPlayerDemoPlaybackViewControllerCurrentItemObservationContext];
mPlaybackView = [AVPlayerLayer playerLayerWithPlayer:self.player];
[self.theView setWantsLayer:YES];
[mPlaybackView setFrame:self.theView.layer.bounds];
[self.theView.layer addSublayer:mPlaybackView];
}
Затем я создаю NSRunLoop для захвата кадра AVPlayerLayer 30 раз в секунду:
framegrabTimer = [NSTimer timerWithTimeInterval:(1/30) target:self selector:@selector(grabFrameFromMovie) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:framegrabTimer forMode:NSDefaultRunLoopMode];
Вот код, который я использую, чтобы захватить фрейм и передать его классу, который обрабатывает QCRenderer:
-(void)grabFrameFromMovie {
CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
CGContextRef theContext = CGBitmapContextCreate(NULL, mPlaybackView.frame.size.width, mPlaybackView.frame.size.height, 8, 4*mPlaybackView.frame.size.width, colorSpace, kCGImageAlphaPremultipliedLast);
[mPlaybackView renderInContext:theContext];
CGImageRef CGImage = CGBitmapContextCreateImage(theContext);
NSImage *image = [[NSImage alloc] initWithCGImage:CGImage size:NSMakeSize(mPlaybackView.frame.size.width, mPlaybackView.frame.size.height)];
[[NSNotificationCenter defaultCenter] postNotificationName:@"AVPlayerLoadedNewFrame" object:[image copy]];
CGContextRelease(theContext);
CGColorSpaceRelease(colorSpace);
CGImageRelease(CGImage); }
Я не могу понять, почему я только проясняюсь. Любая помощь в этом с благодарностью, так как не хватает документации AVFoundation для OS X.