2017-03-05 13 views
5

私は2人のユーザー間でビデオチャットを作成するためにWebRTCを使用しています。私はlocalViewビューのスナップショットを撮りたいと思っています。これには人物の1人が写っています。AVCaptureVideoPreviewLayerのビューのスナップショットを取る

これはUIViewsとビデオストリームを結ぶconfigureLocalPreview方法で私のクラスである:

@IBOutlet var remoteView: RTCEAGLVideoView! 
@IBOutlet var localView: UIView! 

var captureSession: AVCaptureSession? 
var videoSource: RTCAVFoundationVideoSource? 
var videoTrack: RTCVideoTrack? 

func configureLocalPreview() { 
    self.videoTrack = self.signaling.localMediaStream.self.videoTracks.first as! RTCVideoTrack? 
    self.videoSource = (self.videoTrack?.source as? RTCAVFoundationVideoSource) 
    self.captureSession = self.videoSource?.self.captureSession 

    self.previewLayer = AVCaptureVideoPreviewLayer.init(session: self.captureSession) 
    self.previewLayer.frame = self.localView.bounds 
    self.localView.layer.addSublayer(self.previewLayer) 
    self.localView.isUserInteractionEnabled = true 
    //self.localView.layer.position = CGPointMake(100, 100); 
} 

私はスナップショットにアクセスしたい場所で、私が呼ん:

self.localView.pb_takeSnapshot() 

pb_takeSnapshotが来ます別の投稿で見つけたUIView拡張機能からそれは、次のように定義されています:

extension UIView { 
    func pb_takeSnapshot() -> UIImage { 
    UIGraphicsBeginImageContextWithOptions(bounds.size, false, UIScreen.main.scale) 

    drawHierarchy(in: self.bounds, afterScreenUpdates: true) 

    let image = UIGraphicsGetImageFromCurrentImageContext()! 
    UIGraphicsEndImageContext() 
    return image 
    } 
} 

私はXcodeのデバッガで画像を見てみるとき、それは完全に緑に見えると私は(そのビュー内の)iPhoneの画面上で見ることができる人は、、ではありませんそこ:

screenshot of the snapshot

はどのような人が表示されていないことを理由だろうか?それは何とかストリームのスナップ写真を作ることはできませんか?見ていただきありがとうございます!

答えて

2

AVCaptureVideoPreviewLayerはOpenGLレイヤーとして実装されているため、通常のCoreGraphicのコンテキストを使用することはできません。生データにアクセスしようと提案することができます。

デリゲートでAVCaptureVideoDataOutputを追加します。

previewLayer = AVCaptureVideoPreviewLayer(session: captureSession) 

let captureVideoOutput = AVCaptureVideoDataOutput() 
captureVideoOutput.setSampleBufferDelegate(self, queue: DispatchQueue.main) 
captureSession?.addOutput(captureVideoOutput) 

previewLayer.frame = localView.bounds 

AVCaptureVideoDataOutputSampleBufferDelegateにあなたのコントローラ(または何でも)に準拠。

shouldCaptureFrameを宣言し、写真を撮る必要があるときはいつでも設定してください。代理人から

var shouldCaptureFrame: Bool = false 
... 
func takeSnapshot() { 
    shouldCaptureFrame = true 
} 

、実施didOutputSampleBuffer

func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!) { 
    if !shouldCaptureFrame { 
    return 
    } 

    let image = UIImage.from(sampleBuffer: sampleBuffer) 
    shouldCaptureFrame = false 
} 

最後に、from(sampleBuffer:)機能を備えた拡張:

extension UIImage { 

    static func from(sampleBuffer: CMSampleBuffer) -> UIImage? { 
     guard let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else { 
      return nil 
     } 
     CVPixelBufferLockBaseAddress(imageBuffer, CVPixelBufferLockFlags(rawValue: 0)) 
     let baseAddresses = CVPixelBufferGetBaseAddress(imageBuffer) 
     let colorSpace = CGColorSpaceCreateDeviceRGB() 
     let context = CGContext(
      data: baseAddresses, 
      width: CVPixelBufferGetWidth(imageBuffer), 
      height: CVPixelBufferGetHeight(imageBuffer), 
      bitsPerComponent: 8, 
      bytesPerRow: CVPixelBufferGetBytesPerRow(imageBuffer), 
      space: colorSpace, 
      bitmapInfo: CGBitmapInfo.byteOrder32Little.rawValue 
     ) 
     let quartzImage = context?.makeImage() 
     CVPixelBufferUnlockBaseAddress(imageBuffer, CVPixelBufferLockFlags(rawValue: 0)) 

     if let quartzImage = quartzImage { 
      let image = UIImage(cgImage: quartzImage) 
      return image 
     } 

     return nil 
    } 

} 
3

あなたは代わりのUIViewのRTCEAGLVideoViewを使用してlocalViewを作成する必要があります。私は自分のlocalViewに同じものを使用していて、あなたの投稿に記載されているものと同じコードスニペットを使ってスナップショットを撮ることができます。以下は

お使いのカメラを起動して、地元のプレビューが表示されますサンプルコードです:のWebRTCビデオ層のために

class ViewController: UIViewController,RTCEAGLVideoViewDelegate { 

var captureSession: AVCaptureSession? 
var previewLayer :AVCaptureVideoPreviewLayer? 
var peerConnectionFactory: RTCPeerConnectionFactory! 
var videoSource:RTCAVFoundationVideoSource! 
var localTrack :RTCVideoTrack! 

@IBOutlet var myView: UIView! 
override func viewDidLoad() { 
    super.viewDidLoad() 
    /*myView = UIView(frame: CGRect(x: 0, 
           y: 0, 
           width: UIScreen.main.bounds.size.width, 
           height: UIScreen.main.bounds.size.height))*/ 
    startCamera() 
    // Do any additional setup after loading the view, typically from a nib. 
} 

fileprivate func startCamera() { 

    peerConnectionFactory = RTCPeerConnectionFactory() 
    RTCInitializeSSL(); 
    RTCSetupInternalTracer(); 
    RTCSetMinDebugLogLevel(RTCLoggingSeverity.info) 

    videoSource = peerConnectionFactory.avFoundationVideoSource(with: nil); 


    localTrack = peerConnectionFactory.videoTrack(with: videoSource, trackId: "ARDAMSv0") 



    let localScaleX = CGFloat(1.0) 
    let localView : RTCEAGLVideoView = RTCEAGLVideoView(frame: self.view.bounds) 
    self.view.insertSubview(localView, at: 1) 
    localView.frame = self.view.bounds; 
    localView.transform = CGAffineTransform(scaleX: localScaleX, y: 1) 

    localTrack.add(localView) 
} 


override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning() 
    // Dispose of any resources that can be recreated. 
} 

override func viewDidAppear(_ animated: Bool) { 
    //previewLayer?.frame.size = myView.frame.size 
} 

func videoView(_ videoView: RTCEAGLVideoView, didChangeVideoSize size: CGSize) { 
    print("Inside didChangeVideoSize") 
} 

} 
+0

答えていただきありがとうございます。実際のコードをどうやってどのように見えるのか少し混乱しますバージョン。 – Linus

+0

@ Linus私はカメラを起動し、ローカルプレビューを見るために使用できるサンプルコードスニペットを使って投稿を更新しました。 –

1

あなたはビューのRTCEAGLVideoViewを使用する必要があります。詳細については、ここにあるこれらのWebRTCサンプルアプリケーションをご覧くださいAppRTC App

関連する問題