繁体   English   中英

如何在 iOS 中使用 WebRTC 为发布流捕获屏幕截图?

[英]How to capture screenshot for Publish stream using WebRTC in iOS?

在 IOS 的 WebRTC 中,我使用RTCCameraPreviewView播放发布流和RTCMTLVideoView播放远程流。

我可以使用以下代码为远程蒸汽拍摄快照:

UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, 2.0f);
 [self drawViewHierarchyInRect:self.bounds afterScreenUpdates:YES];
 UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
 UIGraphicsEndImageContext();

但是当我使用相同的代码捕获本地流的快照时,我得到了一个空白图像。

请建议,如何为本地流拍摄快照。

在 webRTC 中,当使用RTCCameraPreviewView显示发布流时,您无法拍摄快照,因为 ** RTCCameraPreviewView** 通过AVCaptureVideoPreviewLayer处理并将其实现为 OpenGL 层,因此您不能使用常规 CoreGraphic 的上下文在RTCCameraPreviewView上拍摄快照。 但是我们可以在我们的控制器中覆盖RTCCameraPreviewView captchaSession和 Set AVCaptureVideoDataOutput委托,并获得Frame作为CMSampleBufferRef 为了使其工作,我们需要从“RTCCameraPreviewView”对象获取“AVCaptureSession”引用。

RTCCameraPreviewView *publisherView = [[RTCCameraPreviewView alloc]initWithFrame:self.frame];
       AVCaptureSession *session = publisherView.captureSession;

现在我们可以从 ** AVCaptureSession** 获取可用的 ** AVCaptureVideoDataOutput** 列表

NSArray *dataOutputList = session.outputs

获取 dataOutputList 列表后过滤该数组并找到您的发布者视频播放的正确AVCaptureVideoDataOutput

例如让我们假设

AVCaptureVideoDataOutput*captureVideoOutput = dataOutputList[0];

这意味着索引“0”具有本地发布者视频AVCaptureVideoDataOutput现在参考设置如下的旧代表

id capTchadelegate = captureVideoOutput.sampleBufferDelegate;

然后如下覆盖AVCaptureVideoDataOutputSampleBufferDelegate

[captureVideoOutput setSampleBufferDelegate:self  queue:dispatch_get_main_queue()];

在覆盖委托后实现AVCaptureVideoDataOutputSampleBufferDelegate在你的类 ab 下面

- (void)captureOutput:(AVCaptureOutput *)output didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection;

在这里我们将获得CMSampleBufferRef并将其转换为UIImage

在为AVCaptureVideoDataOutputSampleBufferDelegate获取所需的CMSampleBufferRef图像集委托后,这样您的发布流就不会在同一个调用中被其他接收者卡住

[captureVideoOutput setSampleBufferDelegate:capTchadelegate queue:dispatch_get_main_queue()];

在你的 viewController.swift 文件中

func takeScreenshot(_ shouldSave: Bool = true) {
       var screenshotImage :UIImage?
       let layer = UIApplication.shared.keyWindow!.layer
       let scale = UIScreen.main.scale
       UIGraphicsBeginImageContextWithOptions(layer.frame.size, false, scale)
    self.view.drawHierarchy(in: self.view.bounds, afterScreenUpdates: true)
       screenshotImage = UIGraphicsGetImageFromCurrentImageContext()
       UIGraphicsEndImageContext()
       if let image = screenshotImage, shouldSave {
           UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)
       }
   }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM