From 6ac4a7ae929e81b6a4c5b87aa228b6cf3a47ffea Mon Sep 17 00:00:00 2001 From: Hiroshi Horie <548776+hiroshihorie@users.noreply.github.com> Date: Tue, 23 Nov 2021 08:52:34 +0700 Subject: [PATCH] IPCCapturer --- .../LiveKit/track/capturers/IPCCapturer.swift | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 Sources/LiveKit/track/capturers/IPCCapturer.swift diff --git a/Sources/LiveKit/track/capturers/IPCCapturer.swift b/Sources/LiveKit/track/capturers/IPCCapturer.swift new file mode 100644 index 000000000..5bbe26e46 --- /dev/null +++ b/Sources/LiveKit/track/capturers/IPCCapturer.swift @@ -0,0 +1,72 @@ +import Foundation +import WebRTC +import Promises + +/// Experimental capturer that uses inter-process-communication to receive +/// video buffers +class IPCCapturer: VideoCapturer { + + private let capturer = RTCVideoCapturer() + private let ipcServer = IPCServer() + private let ipcName: String + + init(delegate: RTCVideoCapturerDelegate, ipcName: String) { + self.ipcName = ipcName + super.init(delegate: delegate) + + ipcServer.onReceivedData = { _, messageId, data in + + guard let message = try? IPCMessage(serializedData: data) else { + logger.warning("Failed to decode ipc message") + return + } + + if case let .buffer(bufferMessage) = message.type, + case let .video(videoMessage) = bufferMessage.type { + + // restore pixel buffer from data + let pixelBuffer = CVPixelBuffer.from(bufferMessage.buffer, + width: Int(videoMessage.width), + height: Int(videoMessage.height), + pixelFormat: videoMessage.format) + + // TODO: handle rotation + + delegate.capturer(self.capturer, + didCapture: pixelBuffer, + timeStampNs: bufferMessage.timestampNs, + rotation: ._0) + } + } + } + + override func startCapture() -> Promise { + super.startCapture().then { + // start listening for ipc messages + self.ipcServer.listen(self.ipcName) + } + } + + override func stopCapture() -> Promise { + super.stopCapture().then { + // stop listening for ipc messages + self.ipcServer.close() + } + } +} + +extension LocalVideoTrack { + + public static func createIPCTrack(name: String = Track.screenShareName, + ipcName: String, + source: VideoTrack.Source = .screenShareVideo) -> LocalVideoTrack { + let videoSource = Engine.factory.videoSource() + let capturer = IPCCapturer(delegate: videoSource, ipcName: ipcName) + return LocalVideoTrack( + capturer: capturer, + videoSource: videoSource, + name: name, + source: source + ) + } +}