AVSampleBufferDisplayLayer的快照

时间:2014-10-02 13:59:28

标签: ios

我在AVsampleBufferDisplayLayer上显示了一些视频,并希望捕获此图像并将其保存到相册中。由于AVSampleBufferDisplayLayer继承自CALayer,我认为在renderInContext中使用它是可以接受的。

[targetView.layer addSublayer:avLayer];


UIGraphicsBeginImageContext(targetView.bounds.size);
CGContextRef context = UIGraphicsGetCurrentContext();
[avLayer renderInContext:context];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

UIImageWriteToSavedPhotosAlbum(image,
                                   self,
                                   @selector(image:didFinishSavingWithError:contextInfo:),
                                   NULL);

但这会导致将白色空白图像保存到相册中。 关于我可能出错的地方的任何想法?

2 个答案:

答案 0 :(得分:2)

我没有关于如何使当前方法正常工作的建议,但正确的做法是不使用AVSampleBufferDisplayLayer,而是使用VideoToolbox的VTDecompressionSession来使用H.264解码后的帧将作为CVPixelBuffers传回给您,然后您可以将其转换并保存到磁盘。

答案 1 :(得分:1)

我挣扎了一个星期左右,但最终通过从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);
}

我不知道为什么VTD会支持截图,但AVSampleLayer不支持。似乎它可能是Apple的错误/错误??