Снимок AVSampleBufferDisplayLayer

У меня есть видео, отображаемое на 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 ответа

У меня нет предложений о том, как заставить текущий подход работать, но правильный способ сделать это - вообще не использовать AVSampleBufferDisplayLayer, а вместо этого использовать VTDecompressionSession VideoToolbox, чтобы декодировать кадры H.264 и возвращать их вам как CVPixelBuffers. в обратном вызове, который вы можете затем преобразовать и сохранить на диск.

Я боролся с этим в течение недели или около того, но в итоге исправил это, переключившись с 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??

Другие вопросы по тегам