2012-03-13 6 views
2

私はAVPlayerLayer(CALayerのサブクラス)を持っており、QCRendererに渡すことができるイメージタイプに入る必要があります(QCRendererはNSImagesとCIImagesを受け入れます)。 CGImageRefとそれをNSImageに渡しますが、内容は常にクリアです。AVPlayerがAVPlayerLayerにレンダリングしない

私は2つの理由の一つに、それを絞り込むました:私が正しくNSImageではを作成しておりません

  1. AVPlayerはAVPlayerLayerにレンダリングされません。

私はエラーを起こさず、CALayersの変換に関するいくつかのドキュメントを発見した。また、AVPlayerLayerをNSViewに追加しました。これは空のままなので、2が問題だと思います。

私はAppleのAVPlayerDemoのAVPlayerDemoPlaybackViewControllerの修正版を使用しています。私はそれからインターフェイスコードのすべてを取り除いたので、NSObjectに変換しました。

私は(無効)prepareToPlayAssetでAVPlayerLayerを作成します。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]; 
} 

私は、毎秒AVPlayerLayer 30回のフレームをつかむためにNSRunLoopを作成する:

:ここ

framegrabTimer = [NSTimer timerWithTimeInterval:(1/30) target:self selector:@selector(grabFrameFromMovie) userInfo:nil repeats:YES]; 
[[NSRunLoop currentRunLoop] addTimer:framegrabTimer forMode:NSDefaultRunLoopMode]; 

は、Iフレームを取得し、QCRendererを扱うクラスに渡すために使用するコードであります0

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

なぜ私は明確になっているのか分かりません。 OS Xのための十分なAVFoundationのドキュメントがないとしてこれですべてのヘルプは大幅に高く評価され

私のために
+0

こんにちは。あなたはこの問題で運がありますか?どういうわけか解決しましたか?私はAVPlayerLayerからもスクリーンショットを撮りたいですが、これまでrenderInContextは私にはうまくいきませんでした。 – superjos

+3

私はそれがあなたの問題にどのように関係しているのかは分かりませんが、 'timerWithTimeInterval:(1/30)'はあなたが思うことをしません。両方のオペランドが整数なので '1/30'は0と評価されますので、0.0333333のdouble値を得るには' 1/30'を使うべきです。 – 0xced

答えて

0

その作品:

AVAssetImageGenerator *gen = [[AVAssetImageGenerator alloc] initWithAsset:[[[self player] currentItem] asset]]; 
CGImageRef capture = [gen copyCGImageAtTime:self.player.currentTime actualTime:NULL error:NULL]; 
NSImage *img = [[NSImage alloc] initWithCGImage:capture size:self.playerView.frame.size]; 
0

あなたはCVPixelBufferRefを照会するcopyPixelBufferForItemTimeをAVPlayerItemにAVPlayerItemVideoOutputを追加し、呼び出すことができます指定した時間内にフレームが含まれているオブジェクトは、ここではサンプルコードです:

NSDictionary *pixBuffAttributes = @{                      
    (id)kCVPixelBufferWidthKey:@(nWidth),         
    (id)kCVPixelBufferHeightKey:@(nHeight),         
    (id)kCVPixelBufferCGImageCompatibilityKey:@YES, 
}; 
m_output = [[AVPlayerItemVideoOutput alloc] initWithPixelBufferAttributes:pixBuffAttributes]; 

... 

m_buffer = [m_output copyPixelBufferForItemTime:time itemTimeForDisplay:NULL]; 

CVPixelBufferLockBaseAddress(m_buffer, 0); 
auto *buffer = CVPixelBufferGetBaseAddress(m_buffer); 
frame->width = CVPixelBufferGetWidth(m_buffer); 
frame->height = CVPixelBufferGetHeight(m_buffer); 
frame->widthbytes = CVPixelBufferGetBytesPerRow(m_buffer); 
frame->bufferlen = frame->widthbytes * (uint32)CVPixelBufferGetHeight(m_buffer); 

auto &videoInfo = m_info.video; 
CGDataProviderRef dp = CGDataProviderCreateWithData(nullptr, buffer, frame->bufferlen, nullptr); 
CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB(); 
m_image = CGImageCreate(frame->width, 
         frame->height, 
         8, 
         videoInfo.pixelbits, 
         frame->widthbytes, 
         cs, 
         kCGImageAlphaNoneSkipFirst, 
         dp, 
         nullptr, 
         true, 
         kCGRenderingIntentDefault); 
CGColorSpaceRelease(cs); 
CGDataProviderRelease(dp); 

そして、あなたは、Appleの公式サンプルチェックアウトすることができます:

を3210

Real-timeVideoProcessingUsingAVPlayerItemVideoOutput

関連する問題