0

我一直在使用新的 Video Toolbox 方法来获取 H.264 视频流并使用AVSampleBufferDisplayLayer. 这一切都按预期工作,流看起来很棒。 但是,当我尝试截取整个视图的屏幕截图时,AVSampleBufferDisplayLayer(即解压缩的视频流)的内容不会显示在快照中。 快照显示所有其他 UI 按钮/标签/等。但屏幕截图只显示了AVSampleBufferDisplayLayer(我设置为亮蓝色)的背景颜色,而不是实时视频源。

在下面的方法中(受这篇文章的启发),我SampleBuffer从我的流中取出并排队以显示在AVSampleBufferDisplayLayer. 然后我调用我的方法imageFromLayer:将快照作为UIImage. (然后,我要么在UIImageView imageDisplay中显示该 UIImage ,要么将其保存到设备的本地相机胶卷中以验证其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]; and .modelLayer,但这没有帮助。我尝试过将采样缓冲区排队并在拍摄快照之前等待,我尝试过弄乱 的不透明度和 xPosition AVDisplayLayer...我什至尝试CMTimebaseAVDisplayLayer. 任何提示表示赞赏!

同样根据这篇文章这篇文章,其他人在 iOS 8 中也遇到了类似的快照问题。

4

1 回答 1

0

我通过从 切换到AVSampleDisplayLayer来解决这个问题VTDecompressionSession。在VTDecompression didDecompress回调方法中,我将解压CVImageBufferRefUIImage的图片(

-(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 回答