How to send multiple data at once using Multipeer Connectivity?

51 views Asked by At

I'm trying to send camera frames using the Multipeer Connectivity framework. What I want to do is there will be multiple devices (I'm gonna call it peer) that can connect to a specific host device (I'm gonna call it host), then the peer will stream it's camera frames to the host and the host will show the frames. So far what I've done is this:

Note: I used AVCaptureVideoDataOutputSampleBufferDelegate to retrieve the camera frames. And I have a custom logic that will only send the camera frames 5 FPS.

Sending the video frames from peer to host:

static func sendVideoPreviewFrameCommand(
        using session: MCSession,
        to peers: [MCPeerID],
        imageData: Data,
        timestamp: String) throws {
            // This is just a struct to wrap the camera frames (which is type of `Data` from a `CGImage`)
            let request = PeerRequestMakeSendVideoFrameRequest(imageData, timestamp: timestamp)
            let encoder = JSONEncoder()
            let requestData = try encoder.encode(request)
            try session.send(requestData, toPeers: peers, with: .reliable)
    }

Receving the video frames and show it to the host:

func session(didReceiveCameraFrames frame: Data, from peer: MCPeerID) {
    setPreviewLayerContents(frame, from: peer)
}

private func setPreviewLayerContents(_ data: Data, from peer: MCPeerID) {
    if let view = getPeerView(using: peer) {
        streamingSemaphore.wait()
        // In here, I set that each connected peer has it's own seperate queue to create the `CGImage` from the received `Data`, then I set the `CGImage` to a custom view for each connected peer
        view.receivingQueue.async { [unowned self] in
            let imageSource = CGImageSourceCreateWithData(data as CFData, nil)
            let imageData = CGImageSourceCreateImageAtIndex(imageSource!, 0, nil)
            DispatchQueue.main.async {
                // I set the layer contents using the received `CGImage`
                view.setPreviewImage(imageData)
                self.streamingSemaphore.signal()
            }
        }
    }
}

So far, when the host is only connected to 1 peer, it works as expected. But when I connect to for example 2 peers, the host will stop receiving the camera frames. Sometimes it only receives the camera frames from the last connected peer and the previously connected peer will stop sending its camera frames.

My goal is to all of the connected peers send its camera frames to the host at once. How do I achieve this? If you need more information/code for this please let me know. Thank you.

0

There are 0 answers