I want to send video from a device to another using Multipeer Connectivity framework.
After establishing the connection between the peers I'm capturing the video from the front camera using a regular AVCaptureSession.
I'm following these steps.
1) Open the stream:
func setupStreaming() {
if let stream = p2pSession.startStream() {
stream.delegate = self
stream.schedule(in: RunLoop.main, forMode: .defaultRunLoopMode)
stream.open()
self.outputStream = stream
}
}
The p2pSession.startStream() method creates a stream to the peer in the established MCSession session and returns it if no exception.
2) When the video output notifies a frame has been captured it calls its delegate method
func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!) {
// ¿?
}
3) In the the delegate method of the MCSession I have to get the input stream and extract the data.
func session(_ session: MCSession, didReceive stream: InputStream, withName streamName: String, fromPeer peerID: MCPeerID) {
stream.delegate = self
stream.schedule(in: RunLoop.main, forMode: .defaultRunLoopMode)
stream.open()
// ¿?
}
As you can see steps 2) and 3) are empty. I'm completely lost about how to achieve the conversion between the CMSampleBuffer and the OutputStream, and between the InputStream and the final view that would render each video frame.
I've search a lot and I can't see anything that I can understand completely because I have lacks on streaming, video buffers and related. For example this code, I can't understand exactly what it is doing:
guard let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else {
return
}
let flags = CVPixelBufferLockFlags(rawValue: 0)
CVPixelBufferLockBaseAddress(imageBuffer, flags)
let bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer)
let height = CVPixelBufferGetHeight(imageBuffer)
let src_buff = CVPixelBufferGetBaseAddress(imageBuffer)
let data: NSData = NSData(bytes: src_buff, length: bytesPerRow * height)
CVPixelBufferUnlockBaseAddress(imageBuffer, flags)
let auxData = data as Data
auxData.withUnsafeBytes { (bytes: UnsafePointer<UInt8>) -> Void in
outputStream?.write(bytes, maxLength: auxData.count)
}
I saw an example of this but using MCSession's send(_ data: Data, toPeers peerIDs: [MCPeerID], with mode: MCSessionSendDataMode), not the streaming API (I think that is the correct way to do this).
Also, the docs are very cryptic to me.
Any help will be really appreciated.
Thanks