MCSession 和 AVFoundation 视频流

eme*_*gro 5 avfoundation video-streaming ios multipeer-connectivity

我想使用多点连接框架将视频从一个设备发送到另一个设备。

\n\n

在对等点之间建立连接后,我使用常规方法从前置摄像头捕获视频AVCaptureSession.

\n\n

我正在按照这些步骤操作。

\n\n

1)打开流:

\n\n
func setupStreaming() {\n    if let stream = p2pSession.startStream() {\n        stream.delegate = self\n        stream.schedule(in: RunLoop.main, forMode: .defaultRunLoopMode)\n        stream.open()\n        self.outputStream = stream\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

p2pSession.startStream()方法创建一个到已建立的对等点的流MCSession,如果没有异常则返回它。

\n\n

2)当视频输出通知帧已被捕获时,它会调用其委托方法

\n\n
func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!) {\n    // \xc2\xbf?\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

3)在委托方法中MCSession我必须获取输入流并提取数据。

\n\n
func session(_ session: MCSession, didReceive stream: InputStream, withName streamName: String, fromPeer peerID: MCPeerID) {\n    stream.delegate = self\n    stream.schedule(in: RunLoop.main, forMode: .defaultRunLoopMode)\n    stream.open()        \n    // \xc2\xbf?\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

正如您所看到的,步骤 2) 和 3) 是空的。我完全不知道如何实现 和 之间CMSampleBuffer以及OutputStream之间的转换InputStream和渲染每个视频帧的最终视图之间的转换。

\n\n

我已经搜索了很多,但我看不到任何我能完全理解的东西,因为我缺乏流媒体、视频缓冲区和相关内容。例如这段代码,我无法准确理解它在做什么:

\n\n
guard let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else {\n        return\n    }\nlet flags = CVPixelBufferLockFlags(rawValue: 0)\nCVPixelBufferLockBaseAddress(imageBuffer, flags)\nlet bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer)\nlet height = CVPixelBufferGetHeight(imageBuffer)\nlet src_buff = CVPixelBufferGetBaseAddress(imageBuffer)\nlet data: NSData = NSData(bytes: src_buff, length: bytesPerRow * height)\nCVPixelBufferUnlockBaseAddress(imageBuffer, flags)\nlet auxData = data as Data\nauxData.withUnsafeBytes { (bytes: UnsafePointer<UInt8>) -> Void in\n    outputStream?.write(bytes, maxLength: auxData.count)\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

我看到了一个例子,但是使用了MCSession\'ssend(_ data: Data, toPeers peerIDs: [MCPeerID], with mode: MCSessionSendDataMode),而不是流 API(我认为这是正确的方法)。

\n\n

另外,这些文档对我来说非常神秘。

\n\n

任何帮助将不胜感激。

\n\n

谢谢

\n