0

新しい Video Toolbox メソッドを使用して、H.264 ビデオ ストリームを取得し、AVSampleBufferDisplayLayer. これはすべて意図したとおりに機能し、ストリームは見栄えがします。 しかし、ビュー全体のスクリーンショットを撮ろうとすると、その内容AVSampleBufferDisplayLayer(解凍されたビデオ ストリーム) がスナップショットに表示されません。 スナップショットには、他のすべての UI ボタン​​/ラベルなどが表示されます。しかし、スクリーンショットには (明るい青に設定した) 背景色のみが表示AVSampleBufferDisplayLayerされ、ライブ ビデオ フィードは表示されません。

以下のメソッド (この投稿に触発されたもの) ではSampleBuffer、ストリームから を取得し、キューに表示するようにキューに入れますAVSampleBufferDisplayLayer。次に、メソッドimageFromLayer:を呼び出して、スナップショットを として取得しUIImageます。(次に、その UIImage を UIImageView imageDisplay に表示するかデバイスのローカル カメラ ロールに保存して、どのようにUIImage見えるかを確認します。どちらの方法でも同じ結果が得られます。)

-(void) h264VideoFrame:(CMSampleBufferRef)sample
{
    [self.AVSampleDisplayLayer enqueueSampleBuffer:sample];

    dispatch_sync(dispatch_get_main_queue(), ^(void) {
        UIImage* snapshot = [self imageFromLayer:self.AVSampleDisplayLayer];
        [self.imageDisplay setImage:snapshot];
    });
}

ここでは、 の内容を単純に取得して、AVSampleBufferDisplayLayerに変換しようとしていUIImageます。画面全体をレイヤーとしてこのメ​​ソッドに渡すと、ラベル/ボタン/画像などの他のすべての UI 要素が表示されAVDisplayLayerます。だけを渡すと、AVDisplayLayer青一色のイメージが得られます (背景色が青であるため)。

- (UIImage *)imageFromLayer:(CALayer *)layer
{
    UIGraphicsBeginImageContextWithOptions([layer frame].size, YES, 1.0);

    [layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext();

    //UIImageWriteToSavedPhotosAlbum(outputImage, self, nil, nil);

    UIGraphicsEndImageContext();

    return outputImage;
}

と を使用してみましUIImage snapshot = [self imageFromLayer: self.AVSampleDisplayLayer.presentationLayer];.modelLayerが、役に立ちませんでした。サンプルバッファをキューに入れ、スナップショットを撮る前に待機しようとしました. の不透明度と xPosition をいじってみAVDisplayLayerましCMTimebaseAVDisplayLayer. どんなヒントでも大歓迎です!

また、この投稿およびこの投稿 によると、他の人が iOS 8 のスナップショットで同様の問題を抱えています。

4

1 に答える 1

0

AVSampleDisplayLayerからに切り替えることでこれを修正しましたVTDecompressionSession。コールバック メソッドで、VTDecompression didDecompress解凍した画像 ( ) を次のメソッドに送信してCVImageBufferRef、ビデオ ストリームのスクリーンショットを取得し、それをUIImage.

-(void) screenshotOfVideoStream:(CVImageBufferRef)imageBuffer
{
    CIImage *ciImage = [CIImage imageWithCVPixelBuffer:imageBuffer];
    CIContext *temporaryContext = [CIContext contextWithOptions:nil];
    CGImageRef videoImage = [temporaryContext
                             createCGImage:ciImage
                             fromRect:CGRectMake(0, 0, 
                             CVPixelBufferGetWidth(imageBuffer), 
                             CVPixelBufferGetHeight(imageBuffer))];

    UIImage *image = [[UIImage alloc] initWithCGImage:videoImage];
    [self doSomethingWithOurUIImage:image];
    CGImageRelease(videoImage);
}
于 2015-03-04T16:47:16.583 に答える