diff --git a/.gitmodules b/.gitmodules index 38d4aca6a50..91273bc149d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -15,7 +15,7 @@ url = https://github.com/telegramdesktop/libtgvoip.git [submodule "submodules/TgVoipWebrtc/tgcalls"] path = submodules/TgVoipWebrtc/tgcalls - url = https://github.com/TelegramMessenger/tgcalls.git + url = git@bitbucket.org:mobyrix/tgcalls.git [submodule "third-party/libvpx/libvpx"] path = third-party/libvpx/libvpx url = https://github.com/webmproject/libvpx.git @@ -26,7 +26,7 @@ # Perhaps the crash is related to the minimum version of iOS (we have iOS 14, telegram has iOS 12). [submodule "third-party/webrtc/webrtc"] path = third-party/webrtc/webrtc - url = https://github.com/denis15yo/webrtc.git + url = https://github.com/nicegram/webrtc.git [submodule "third-party/libx264/x264"] path = third-party/libx264/x264 url = https://github.com/mirror/x264.git diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index fc112237f35..3ec05659e50 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -2981,7 +2981,7 @@ "general": { "bzlTransitiveDigest": "YjE3dFjYQ4sj5gn2Iz1cWVK14/ZJ5cmnAUUGjDbACAA=", "recordedFileInputs": { - "@@//Package.resolved": "30140fa448ac62bfa0781affd60171e7fbacc1f2d1e0f02a336c356162c102c7", + "@@//Package.resolved": "7dcdf10782a677ab83a0e7eabc1e9ad8029e1ca72572677acfa1e52a1aa7db90", "@@//Package.swift": "fb3cb1d48066e64f8bf17fe1a49f689b7a6bf4bfc07aa90b9b80a02188501951" }, "recordedDirentsInputs": {}, @@ -3082,7 +3082,7 @@ "ruleClassName": "swift_package", "attributes": { "bazel_package_name": "swiftpkg_swiftui_flow", - "commit": "9d122ace53e143dc3e1bf61c01a024535b0c7ab7", + "commit": "3086a602b98155eec28b4be79210d6cb1a43e339", "remote": "https://github.com/denis15yo/SwiftUI-Flow.git", "init_submodules": false, "recursive_init_submodules": true, @@ -3226,7 +3226,7 @@ "ruleClassName": "swift_package", "attributes": { "bazel_package_name": "swiftpkg_walletconnectswiftv2", - "commit": "b6e9e37ab5981444f3898653c34fd39284534aad", + "commit": "2d0c59f682f1c1395b3c2f6e27eb020087952df3", "remote": "https://github.com/WalletConnect/WalletConnectSwiftV2.git", "init_submodules": false, "recursive_init_submodules": true, @@ -3532,7 +3532,7 @@ "ruleClassName": "swift_package", "attributes": { "bazel_package_name": "swiftpkg_grdb.swift", - "commit": "afc958017ee4feefd3c61c8e2cddf81d079d2e39", + "commit": "156d630c7a4175ddf4d529244f4672428cc6e2fc", "remote": "https://github.com/denis15yo/GRDB.swift.git", "init_submodules": false, "recursive_init_submodules": true, @@ -3568,7 +3568,7 @@ "ruleClassName": "swift_package", "attributes": { "bazel_package_name": "swiftpkg_floatingpanel", - "commit": "71f419a3cd212afc7615e2179c2fec1df1aa74da", + "commit": "b6e8928b1a3ad909e6db6a0278d286c33cfd0dc3", "remote": "https://github.com/scenee/FloatingPanel", "init_submodules": false, "recursive_init_submodules": true, @@ -3658,7 +3658,7 @@ "ruleClassName": "swift_package", "attributes": { "bazel_package_name": "swiftpkg_wallet_core", - "commit": "160a6e6275d25c0edb91823ae62c605d3d66c013", + "commit": "db50956fe49d7feb5aca3a4406f49b722e5cfab5", "remote": "https://github.com/trustwallet/wallet-core.git", "init_submodules": false, "recursive_init_submodules": true, @@ -3712,7 +3712,7 @@ "ruleClassName": "swift_package", "attributes": { "bazel_package_name": "swiftpkg_nicegram_wallet_ios", - "commit": "458be079925da10ff15a2b41961ae3bfb4468835", + "commit": "d2655c574276adaf88ffd8d618b766a8d308c027", "remote": "git@bitbucket.org:mobyrix/nicegram-wallet-ios.git", "init_submodules": false, "recursive_init_submodules": true, diff --git a/Package.resolved b/Package.resolved index 5f40f87dd88..49443b1e212 100644 --- a/Package.resolved +++ b/Package.resolved @@ -123,7 +123,7 @@ "location" : "git@bitbucket.org:mobyrix/nicegram-assistant-ios.git", "state" : { "branch" : "develop", - "revision" : "b35ee8e950f4ca23b2d2403c0ae8f43ef8196849" + "revision" : "fda1e89c94fc546d2762d0b2d754e9654965774f" } }, { @@ -132,7 +132,7 @@ "location" : "git@bitbucket.org:mobyrix/nicegram-wallet-ios.git", "state" : { "branch" : "develop", - "revision" : "24dc20049e0fb3271f191cd5d1ff3280ffeaa735" + "revision" : "d2655c574276adaf88ffd8d618b766a8d308c027" } }, { diff --git a/submodules/TelegramCallsUI/Sources/PresentationCall.swift b/submodules/TelegramCallsUI/Sources/PresentationCall.swift index 8b40e8d4f11..7af4ca8228e 100644 --- a/submodules/TelegramCallsUI/Sources/PresentationCall.swift +++ b/submodules/TelegramCallsUI/Sources/PresentationCall.swift @@ -560,6 +560,9 @@ public final class PresentationCallImpl: PresentationCall { self.audioSessionShouldBeActive.set(true) } case let .active(id, key, _, connections, maxLayer, version, customParameters, allowsP2P): + // MARK: Nicegram NCG-5828 call recording + self.sharedAudioDevice?.startNicegramRecording() + // self.audioSessionShouldBeActive.set(true) if let _ = audioSessionControl, !wasActive || previousControl == nil { let logName = "\(id.id)_\(id.accessHash)" @@ -627,6 +630,11 @@ public final class PresentationCallImpl: PresentationCall { } } case let .terminated(_, _, options): + // MARK: Nicegram NCG-5828 call recording + self.sharedAudioDevice?.stopNicegramRecording { [weak self] path, duration, data in + self?.saveCall(with: path, duration: duration, data: data) + } + // self.audioSessionShouldBeActive.set(true) if wasActive { let debugLogValue = Promise() @@ -1068,4 +1076,66 @@ public final class PresentationCallImpl: PresentationCall { self.useFrontCamera = !self.useFrontCamera self.videoCapturer?.switchVideoInput(isFront: self.useFrontCamera) } + + // MARK: Nicegram NCG-5828 call recording + private func saveCall(with path: String, duration: Double, data: Data) { + let dateFormatter = DateFormatter() + dateFormatter.dateFormat = "yyyy-MM-dd_HH:mm:ss" + + let date = Date() + + let id32 = Int32.random(in: 0 ... Int32.max) + let peerId = self.context.account.peerId + let messageId = MessageId( + peerId: peerId, + namespace: Namespaces.Message.Local, + id: id32 + ) + + let id = Int64.random(in: 0 ... Int64.max) + let resource = LocalFileReferenceMediaResource( + localFilePath: path, + randomId: id + ) + + let file = TelegramMediaFile( + fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: id), + partialReference: nil, + resource: resource, + previewRepresentations: [], + videoThumbnails: [], + immediateThumbnailData: nil, + mimeType: "audio/wav", + size: nil, + attributes: [.Audio( + isVoice: false, + duration: Int(duration), + title: dateFormatter.string(from: date), + performer: nil, + waveform: data) + ] + ) + + let message = StoreMessage( + id: messageId, + globallyUniqueId: nil, + groupingKey: nil, + threadId: nil, + timestamp: Int32(date.timeIntervalSince1970), + flags: .init(), + tags: .init(), + globalTags: .init(), + localTags: .init(), + forwardInfo: nil, + authorId: .init(namespace: peerId.namespace, id: peerId.id), + text: "", + attributes: [], + media: [file] + ) + + _ = (self.context.account.postbox.transaction { transaction in + transaction.addMessages([message], location: .Random) + }).start() + } + // } diff --git a/submodules/TelegramVoip/Sources/OngoingCallContext.swift b/submodules/TelegramVoip/Sources/OngoingCallContext.swift index da23074d610..88a7b28d92a 100644 --- a/submodules/TelegramVoip/Sources/OngoingCallContext.swift +++ b/submodules/TelegramVoip/Sources/OngoingCallContext.swift @@ -759,6 +759,24 @@ public final class OngoingCallContext { CallAudioTone(samples: tone.samples, sampleRate: tone.sampleRate, loopCount: tone.loopCount) }) } + + // MARK: Nicegram NCG-5828 call recording + public func initNicegramCallRecording(path: String) { + self.impl.initNicegramCallRecording(path) + } + + public func startNicegramRecording() { + self.impl.startNicegramRecording() + } + + public func stopNicegramRecording(callback: ((String, Double, Data) -> Void)?) { + self.impl.stopNicegramRecording(callback) + } + + public func setRecordOutputFolder(path: String) { + self.impl.setRecordOutputFolder(path) + } + // } public static func setupAudioSession() { diff --git a/submodules/TgVoipWebrtc/PublicHeaders/TgVoipWebrtc/OngoingCallThreadLocalContext.h b/submodules/TgVoipWebrtc/PublicHeaders/TgVoipWebrtc/OngoingCallThreadLocalContext.h index 8b2c52d3cd9..35bc2e291f6 100644 --- a/submodules/TgVoipWebrtc/PublicHeaders/TgVoipWebrtc/OngoingCallThreadLocalContext.h +++ b/submodules/TgVoipWebrtc/PublicHeaders/TgVoipWebrtc/OngoingCallThreadLocalContext.h @@ -31,6 +31,12 @@ - (void)setTone:(CallAudioTone * _Nullable)tone; +// MARK: Nicegram NCG-5828 call recording +-(void)InitNicegramCallRecording:(NSString* _Nonnull)path; +-(void)StartNicegramRecording; +-(void)StopNicegramRecording:(void(^_Nullable)(NSString* _Nonnull, double, NSData* _Nonnull))completion; +-(void)SetRecordOutputFolder:(NSString* _Nonnull)path; +// @end @interface OngoingCallConnectionDescriptionWebrtc : NSObject diff --git a/submodules/TgVoipWebrtc/Sources/OngoingCallThreadLocalContext.mm b/submodules/TgVoipWebrtc/Sources/OngoingCallThreadLocalContext.mm index fe3df0061a6..31f91052906 100644 --- a/submodules/TgVoipWebrtc/Sources/OngoingCallThreadLocalContext.mm +++ b/submodules/TgVoipWebrtc/Sources/OngoingCallThreadLocalContext.mm @@ -118,6 +118,15 @@ virtual void start() override { _audioDeviceModule->InternalStartPlayout(); } //_audioDeviceModule->InternalStartRecording(); + // MARK: Nicegram NCG-5828 call recording + NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); + NSString *documentsDirectory = [paths objectAtIndex:0]; + NSString* path = [NSString stringWithFormat:@"%@/%@", + documentsDirectory, + @"nicegram_saved_calls" + ]; + _audioDeviceModule->InitNicegramCallRecording([path cStringUsingEncoding: NSUTF8StringEncoding]); + // } } @@ -149,6 +158,42 @@ - (void)setTone:(CallAudioTone * _Nullable)tone { }); } +// MARK: Nicegram NCG-5828 call recording +-(void)InitNicegramCallRecording:(NSString* _Nonnull)path { + _audioDeviceModule->perform([path](tgcalls::SharedAudioDeviceModule *audioDeviceModule) { + const char *utfPath = [path UTF8String]; + audioDeviceModule->audioDeviceModule()->InitNicegramCallRecording(utfPath); + }); +} + +-(void)StartNicegramRecording { + _audioDeviceModule->perform([](tgcalls::SharedAudioDeviceModule *audioDeviceModule) { + audioDeviceModule->audioDeviceModule()->StartNicegramRecording(); + }); +} + +-(void)StopNicegramRecording:(void(^_Nullable)(NSString* _Nonnull, double, NSData* _Nonnull))completion { + _audioDeviceModule->perform([completion](tgcalls::SharedAudioDeviceModule *audioDeviceModule) { + audioDeviceModule->audioDeviceModule()->StopNicegramRecording([completion](const std::string& outputFilePath, + double durationInSeconds, + std::vector rawData) { + NSString *path = [NSString stringWithUTF8String: outputFilePath.c_str()]; + NSData *data = [NSData dataWithBytes: rawData.data() length: sizeof(rawData)]; + if (completion != NULL) { + completion(path, durationInSeconds, data); + } + }); + }); +} + +-(void)SetRecordOutputFolder:(NSString* _Nonnull)path { + _audioDeviceModule->perform([path](tgcalls::SharedAudioDeviceModule *audioDeviceModule) { + const char *utfPath = [path UTF8String]; + audioDeviceModule->audioDeviceModule()->SetRecordOutputFolder(utfPath); + }); +} +// + - (std::shared_ptr>)getAudioDeviceModule { return _audioDeviceModule; } diff --git a/submodules/TgVoipWebrtc/tgcalls b/submodules/TgVoipWebrtc/tgcalls index 8344f8ca2a0..c879c0f496a 160000 --- a/submodules/TgVoipWebrtc/tgcalls +++ b/submodules/TgVoipWebrtc/tgcalls @@ -1 +1 @@ -Subproject commit 8344f8ca2a043d0812743260c31a086a82190489 +Subproject commit c879c0f496a12e2c79235ff9529c7a745558063b diff --git a/third-party/webrtc/webrtc b/third-party/webrtc/webrtc index c75f2a397ec..731c1599867 160000 --- a/third-party/webrtc/webrtc +++ b/third-party/webrtc/webrtc @@ -1 +1 @@ -Subproject commit c75f2a397ec3c7db12677b39b52d2b3f8ee9161e +Subproject commit 731c15998672bd3b5ebc52975834e17ea63b1efb