Видеопоток в AVSampleBufferDisplayLayer не отображается на скриншоте
Я использовал новые методы Video Toolbox, чтобы взять видеопоток H.264 и отобразить его в контроллере вида, используя AVSampleBufferDisplayLayer
, Это все работает, как задумано, и поток выглядит великолепно. Однако, когда я пытаюсь сделать скриншот всего представления, содержимое AVSampleBufferDisplayLayer
(то есть распакованный видеопоток) не отображаются на снимке. Снимок показывает все другие кнопки пользовательского интерфейса / метки / и т.д. но скриншот показывает только цвет фона 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
, Если я передам весь экран в этот метод в качестве слоя, будут отображаться все другие элементы пользовательского интерфейса, такие как ярлыки / кнопки / изображения, кроме 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
... Я даже пытался установить разные значения для CMTimebase
из AVDisplayLayer
, Любые советы приветствуются!
Также согласно этому посту и этому посту у других людей возникают похожие проблемы со снимками в iOS 8.
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);
}