Basic proof of concept

This commit is contained in:
Niels Andriesse 2021-08-13 13:47:22 +10:00
parent 56bd59c4ee
commit 876814dd43
8 changed files with 33 additions and 37 deletions

10
Podfile
View File

@ -6,6 +6,7 @@ use_frameworks!
target 'Session' do
pod 'AFNetworking', inhibit_warnings: true
pod 'CryptoSwift', :inhibit_warnings => true
pod 'GoogleWebRTC', :inhibit_warnings => true
pod 'Mantle', git: 'https://github.com/signalapp/Mantle', branch: 'signal-master', :inhibit_warnings => true
pod 'NVActivityIndicatorView', :inhibit_warnings => true
pod 'PromiseKit', :inhibit_warnings => true
@ -13,7 +14,6 @@ target 'Session' do
pod 'Reachability', :inhibit_warnings => true
pod 'SocketRocket', '~> 0.5.1', :inhibit_warnings => true
pod 'Sodium', '~> 0.8.0', :inhibit_warnings => true
pod 'WebRTC', '~> 63.11', :inhibit_warnings => true
pod 'YapDatabase/SQLCipher', :git => 'https://github.com/loki-project/session-ios-yap-database.git', branch: 'signal-release', :inhibit_warnings => true
pod 'YYImage', git: 'https://github.com/signalapp/YYImage', :inhibit_warnings => true
pod 'ZXingObjC', :inhibit_warnings => true
@ -23,20 +23,20 @@ target 'SessionShareExtension' do
pod 'AFNetworking', inhibit_warnings: true
pod 'CryptoSwift', :inhibit_warnings => true
pod 'Curve25519Kit', git: 'https://github.com/signalapp/Curve25519Kit.git', :inhibit_warnings => true
pod 'GoogleWebRTC', :inhibit_warnings => true
pod 'Mantle', git: 'https://github.com/signalapp/Mantle', branch: 'signal-master', :inhibit_warnings => true
pod 'PromiseKit', :inhibit_warnings => true
pod 'PureLayout', '~> 3.1.8', :inhibit_warnings => true
pod 'SignalCoreKit', git: 'https://github.com/signalapp/SignalCoreKit.git', :inhibit_warnings => true
pod 'SocketRocket', '~> 0.5.1', :inhibit_warnings => true
pod 'WebRTC', '~> 63.11', :inhibit_warnings => true
pod 'YapDatabase/SQLCipher', :git => 'https://github.com/loki-project/session-ios-yap-database.git', branch: 'signal-release', :inhibit_warnings => true
end
target 'SessionNotificationServiceExtension' do
pod 'Curve25519Kit', git: 'https://github.com/signalapp/Curve25519Kit.git', :inhibit_warnings => true
pod 'GoogleWebRTC', :inhibit_warnings => true
pod 'SignalCoreKit', git: 'https://github.com/signalapp/SignalCoreKit.git', :inhibit_warnings => true
pod 'SocketRocket', '~> 0.5.1', :inhibit_warnings => true
pod 'WebRTC', '~> 63.11', :inhibit_warnings => true
pod 'YapDatabase/SQLCipher', :git => 'https://github.com/loki-project/session-ios-yap-database.git', branch: 'signal-release', :inhibit_warnings => true
end
@ -44,6 +44,7 @@ target 'SignalUtilitiesKit' do
pod 'AFNetworking', inhibit_warnings: true
pod 'CryptoSwift', :inhibit_warnings => true
pod 'Curve25519Kit', git: 'https://github.com/signalapp/Curve25519Kit.git', :inhibit_warnings => true
pod 'GoogleWebRTC', :inhibit_warnings => true
pod 'GRKOpenSSLFramework', :inhibit_warnings => true
pod 'HKDFKit', :inhibit_warnings => true
pod 'Mantle', git: 'https://github.com/signalapp/Mantle', branch: 'signal-master', :inhibit_warnings => true
@ -55,7 +56,6 @@ target 'SignalUtilitiesKit' do
pod 'SignalCoreKit', git: 'https://github.com/signalapp/SignalCoreKit.git', :inhibit_warnings => true
pod 'SocketRocket', '~> 0.5.1', :inhibit_warnings => true
pod 'SwiftProtobuf', '~> 1.5.0', :inhibit_warnings => true
pod 'WebRTC', '~> 63.11', :inhibit_warnings => true
pod 'YapDatabase/SQLCipher', :git => 'https://github.com/loki-project/session-ios-yap-database.git', branch: 'signal-release', :inhibit_warnings => true
pod 'YYImage', git: 'https://github.com/signalapp/YYImage', :inhibit_warnings => true
end
@ -68,6 +68,7 @@ target 'SessionMessagingKit' do
pod 'AFNetworking', inhibit_warnings: true
pod 'CryptoSwift', :inhibit_warnings => true
pod 'Curve25519Kit', git: 'https://github.com/signalapp/Curve25519Kit.git', :inhibit_warnings => true
pod 'GoogleWebRTC', :inhibit_warnings => true
pod 'HKDFKit', :inhibit_warnings => true
pod 'Mantle', git: 'https://github.com/signalapp/Mantle', branch: 'signal-master', :inhibit_warnings => true
pod 'PromiseKit', :inhibit_warnings => true
@ -78,7 +79,6 @@ target 'SessionMessagingKit' do
pod 'SocketRocket', '~> 0.5.1', :inhibit_warnings => true
pod 'Sodium', '~> 0.8.0', :inhibit_warnings => true
pod 'SwiftProtobuf', '~> 1.5.0', :inhibit_warnings => true
pod 'WebRTC', '~> 63.11', :inhibit_warnings => true
pod 'YapDatabase/SQLCipher', :git => 'https://github.com/loki-project/session-ios-yap-database.git', branch: 'signal-release', :inhibit_warnings => true
end

View File

@ -21,6 +21,7 @@ PODS:
- Curve25519Kit (2.1.0):
- CocoaLumberjack
- SignalCoreKit
- GoogleWebRTC (1.1.31999)
- GRKOpenSSLFramework (1.0.2.20)
- HKDFKit (0.0.3)
- Mantle (2.1.0):
@ -52,7 +53,6 @@ PODS:
- SQLCipher/standard (4.4.0):
- SQLCipher/common
- SwiftProtobuf (1.5.0)
- WebRTC (63.11.20455)
- YapDatabase/SQLCipher (3.1.1):
- YapDatabase/SQLCipher/Core (= 3.1.1)
- YapDatabase/SQLCipher/Extensions (= 3.1.1)
@ -126,6 +126,7 @@ DEPENDENCIES:
- AFNetworking
- CryptoSwift
- Curve25519Kit (from `https://github.com/signalapp/Curve25519Kit.git`)
- GoogleWebRTC
- GRKOpenSSLFramework
- HKDFKit
- Mantle (from `https://github.com/signalapp/Mantle`, branch `signal-master`)
@ -138,7 +139,6 @@ DEPENDENCIES:
- SocketRocket (~> 0.5.1)
- Sodium (~> 0.8.0)
- SwiftProtobuf (~> 1.5.0)
- WebRTC (~> 63.11)
- YapDatabase/SQLCipher (from `https://github.com/loki-project/session-ios-yap-database.git`, branch `signal-release`)
- YYImage (from `https://github.com/signalapp/YYImage`)
- ZXingObjC
@ -148,6 +148,7 @@ SPEC REPOS:
- AFNetworking
- CocoaLumberjack
- CryptoSwift
- GoogleWebRTC
- GRKOpenSSLFramework
- HKDFKit
- NVActivityIndicatorView
@ -159,7 +160,6 @@ SPEC REPOS:
- Sodium
- SQLCipher
- SwiftProtobuf
- WebRTC
- ZXingObjC
EXTERNAL SOURCES:
@ -198,6 +198,7 @@ SPEC CHECKSUMS:
CocoaLumberjack: bd155f2dd06c0e0b03f876f7a3ee55693122ec94
CryptoSwift: 093499be1a94b0cae36e6c26b70870668cb56060
Curve25519Kit: e63f9859ede02438ae3defc5e1a87e09d1ec7ee6
GoogleWebRTC: b39a78c4f5cc6b0323415b9233db03a2faa7b0f0
GRKOpenSSLFramework: dc635b0a9d4cd8af2a9ff80a61e779e21b69dfd8
HKDFKit: c058305d6f64b84f28c50bd7aa89574625bcb62a
Mantle: 2fa750afa478cd625a94230fbf1c13462f29395b
@ -211,11 +212,10 @@ SPEC CHECKSUMS:
Sodium: 63c0ca312a932e6da481689537d4b35568841bdc
SQLCipher: e434ed542b24f38ea7b36468a13f9765e1b5c072
SwiftProtobuf: 241400280f912735c1e1b9fe675fdd2c6c4d42e2
WebRTC: f2a6203584745fe53532633397557876b5d71640
YapDatabase: b418a4baa6906e8028748938f9159807fd039af4
YYImage: 6db68da66f20d9f169ceb94dfb9947c3867b9665
ZXingObjC: fdbb269f25dd2032da343e06f10224d62f537bdb
PODFILE CHECKSUM: 0f0ee15979921c085945dc1cacb0fd1fd380b77d
PODFILE CHECKSUM: 215e4f2af32f65d98d1442e6ec0df3576c994a02
COCOAPODS: 1.10.1

View File

@ -4251,6 +4251,7 @@
"${BUILT_PRODUCTS_DIR}/AFNetworking/AFNetworking.framework",
"${BUILT_PRODUCTS_DIR}/CocoaLumberjack/CocoaLumberjack.framework",
"${BUILT_PRODUCTS_DIR}/CryptoSwift/CryptoSwift.framework",
"${PODS_ROOT}/GoogleWebRTC/Frameworks/frameworks/WebRTC.framework",
"${BUILT_PRODUCTS_DIR}/Mantle/Mantle.framework",
"${BUILT_PRODUCTS_DIR}/NVActivityIndicatorView/NVActivityIndicatorView.framework",
"${BUILT_PRODUCTS_DIR}/PromiseKit/PromiseKit.framework",
@ -4259,7 +4260,6 @@
"${BUILT_PRODUCTS_DIR}/SQLCipher/SQLCipher.framework",
"${BUILT_PRODUCTS_DIR}/SocketRocket/SocketRocket.framework",
"${BUILT_PRODUCTS_DIR}/Sodium/Sodium.framework",
"${PODS_ROOT}/WebRTC/WebRTC.framework",
"${BUILT_PRODUCTS_DIR}/YYImage/YYImage.framework",
"${BUILT_PRODUCTS_DIR}/YapDatabase/YapDatabase.framework",
"${BUILT_PRODUCTS_DIR}/ZXingObjC/ZXingObjC.framework",
@ -4275,6 +4275,7 @@
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AFNetworking.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CocoaLumberjack.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CryptoSwift.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/WebRTC.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Mantle.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NVActivityIndicatorView.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PromiseKit.framework",
@ -4283,7 +4284,6 @@
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SQLCipher.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SocketRocket.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Sodium.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/WebRTC.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YYImage.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YapDatabase.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ZXingObjC.framework",

View File

@ -4,6 +4,7 @@ import WebRTC
final class CallVC : UIViewController, CameraCaptureDelegate, CallManagerDelegate, MockWebSocketDelegate {
private let videoCallVC = VideoCallVC()
let videoCapturer: RTCVideoCapturer = RTCCameraVideoCapturer(delegate: CallManager.shared.localVideoSource)
private var messageQueue: [String] = []
private var isConnected = false {
didSet {
@ -43,31 +44,25 @@ final class CallVC : UIViewController, CameraCaptureDelegate, CallManagerDelegat
// MARK: Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
setUpCamera()
embedVideoCallVC()
view.addSubview(containerView)
containerView.pin(to: view)
}
private func setUpCamera() {
touch(CallManager.shared)
CallManager.shared.delegate = self
CameraManager.shared.delegate = self
CameraManager.shared.prepare()
}
private func embedVideoCallVC() {
addChild(videoCallVC)
containerView.addSubview(videoCallVC.view)
videoCallVC.view.translatesAutoresizingMaskIntoConstraints = false
videoCallVC.view.pin(to: containerView)
view.addSubview(containerView)
containerView.pin(to: view)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
CameraManager.shared.start()
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
CameraManager.shared.stop()
}
@ -157,7 +152,6 @@ final class CallVC : UIViewController, CameraCaptureDelegate, CallManagerDelegat
]
guard let data = try? JSONSerialization.data(withJSONObject: message, options: [.prettyPrinted]) else { return }
MockWebSocket.shared.send(data)
CallManager.shared.delegate = self
if isInitiator {
CallManager.shared.initiateCall().retainUntilComplete()
}

View File

@ -24,13 +24,14 @@ final class CameraManager : NSObject {
private override init() { }
func prepare() {
captureSession.sessionPreset = .low
if let videoCaptureDevice = videoCaptureDevice,
let videoInput = try? AVCaptureDeviceInput(device: videoCaptureDevice), captureSession.canAddInput(videoInput) {
captureSession.addInput(videoInput)
}
if captureSession.canAddOutput(videoDataOutput) {
captureSession.addOutput(videoDataOutput)
videoDataOutput.videoSettings = [kCVPixelBufferPixelFormatTypeKey as String: Int(kCVPixelFormatType_32BGRA)]
videoDataOutput.videoSettings = [ kCVPixelBufferPixelFormatTypeKey as String : Int(kCVPixelFormatType_32BGRA) ]
videoDataOutput.setSampleBufferDelegate(self, queue: dataOutputQueue)
videoDataOutput.connection(with: .video)?.videoOrientation = .portrait
videoDataOutput.connection(with: .video)?.automaticallyAdjustsVideoMirroring = false

View File

@ -51,8 +51,10 @@ extension VideoCallVC : CameraCaptureDelegate {
func captureVideoOutput(sampleBuffer: CMSampleBuffer) {
guard let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else { return }
let rtcpixelBuffer = RTCCVPixelBuffer(pixelBuffer: pixelBuffer)
let timeStampNs = Int64(CMTimeGetSeconds(CMSampleBufferGetPresentationTimeStamp(sampleBuffer)) * 1000000000)
let videoFrame = RTCVideoFrame(buffer: rtcpixelBuffer, rotation: RTCVideoRotation._0, timeStampNs: timeStampNs)
let timestamp = CMTimeGetSeconds(CMSampleBufferGetPresentationTimeStamp(sampleBuffer))
let timestampNs = Int64(timestamp * 1000000000)
let videoFrame = RTCVideoFrame(buffer: rtcpixelBuffer, rotation: RTCVideoRotation._0, timeStampNs: timestampNs)
videoFrame.timeStamp = Int32(timestamp)
CallManager.shared.handleLocalFrameCaptured(videoFrame)
}
}

View File

@ -11,6 +11,7 @@ extension CallManager {
}
public func handleLocalFrameCaptured(_ videoFrame: RTCVideoFrame) {
guard let videoCapturer = delegate?.videoCapturer else { return }
localVideoSource.capturer(videoCapturer, didCapture: videoFrame)
}
}

View File

@ -2,6 +2,7 @@ import PromiseKit
import WebRTC
public protocol CallManagerDelegate : AnyObject {
var videoCapturer: RTCVideoCapturer { get }
func callManager(_ callManager: CallManager, sendData data: Data)
}
@ -23,6 +24,7 @@ public final class CallManager : NSObject, RTCPeerConnectionDelegate {
internal lazy var peerConnection: RTCPeerConnection = {
let configuration = RTCConfiguration()
configuration.iceServers = [ RTCIceServer(urlStrings: MockCallConfig.default.webRTCICEServers) ]
configuration.iceTransportPolicy = .all
// TODO: Do these constraints make sense?
let constraints = RTCMediaConstraints(mandatoryConstraints: [:], optionalConstraints: [ "DtlsSrtpKeyAgreement" : "true" ])
return factory.peerConnection(with: configuration, constraints: constraints, delegate: self)
@ -50,20 +52,16 @@ public final class CallManager : NSObject, RTCPeerConnectionDelegate {
}()
// Video
internal lazy var localVideoSource: RTCVideoSource = {
return factory.avFoundationVideoSource(with: nil)
public lazy var localVideoSource: RTCVideoSource = {
return factory.videoSource()
}()
internal lazy var localVideoTrack: RTCVideoTrack = {
return factory.videoTrack(with: localVideoSource, trackId: "ARDAMSv0")
}()
internal lazy var videoCapturer: RTCVideoCapturer = {
return RTCCameraVideoCapturer(delegate: localVideoSource)
}()
internal lazy var remoteVideoTrack: RTCVideoTrack? = {
return peerConnection.receivers.first { $0.track.kind == "video" }?.track as? RTCVideoTrack
return peerConnection.receivers.first { $0.track?.kind == "video" }?.track as? RTCVideoTrack
}()
// Stream