diff --git a/submodules/TelegramAudio/Sources/ManagedAudioSession.swift b/submodules/TelegramAudio/Sources/ManagedAudioSession.swift index 2c0f4c0227..eb42a04996 100644 --- a/submodules/TelegramAudio/Sources/ManagedAudioSession.swift +++ b/submodules/TelegramAudio/Sources/ManagedAudioSession.swift @@ -209,6 +209,7 @@ public final class ManagedAudioSession { private let isActiveSubscribers = Bag<(Bool) -> Void>() private let isPlaybackActiveSubscribers = Bag<(Bool) -> Void>() + private var isActiveValue: Bool = false private var callKitAudioSessionIsActive: Bool = false public init() { @@ -392,7 +393,7 @@ public final class ManagedAudioSession { let queue = self.queue return Signal { [weak self] subscriber in if let strongSelf = self { - subscriber.putNext(strongSelf.currentTypeAndOutputMode != nil) + subscriber.putNext(strongSelf.isActiveValue || strongSelf.callKitAudioSessionIsActive) let index = strongSelf.isActiveSubscribers.add({ value in subscriber.putNext(value) @@ -686,7 +687,6 @@ public final class ManagedAudioSession { self.deactivateTimer?.invalidate() self.deactivateTimer = nil - let wasActive = self.currentTypeAndOutputMode != nil let wasPlaybackActive = self.currentTypeAndOutputMode?.0.isPlay ?? false self.currentTypeAndOutputMode = nil @@ -709,10 +709,9 @@ public final class ManagedAudioSession { } } - if wasActive { - for subscriber in self.isActiveSubscribers.copyItems() { - subscriber(false) - } + self.isActiveValue = false + for subscriber in self.isActiveSubscribers.copyItems() { + subscriber(self.isActiveValue || self.callKitAudioSessionIsActive) } if wasPlaybackActive { for subscriber in self.isPlaybackActiveSubscribers.copyItems() { @@ -725,7 +724,6 @@ public final class ManagedAudioSession { self.deactivateTimer?.invalidate() self.deactivateTimer = nil - let wasActive = self.currentTypeAndOutputMode != nil let wasPlaybackActive = self.currentTypeAndOutputMode?.0.isPlay ?? false if self.currentTypeAndOutputMode == nil || self.currentTypeAndOutputMode! != (type, outputMode) { @@ -782,10 +780,9 @@ public final class ManagedAudioSession { } } - if !wasActive { - for subscriber in self.isActiveSubscribers.copyItems() { - subscriber(true) - } + self.isActiveValue = true + for subscriber in self.isActiveSubscribers.copyItems() { + subscriber(self.isActiveValue || self.callKitAudioSessionIsActive) } if !wasPlaybackActive && (self.currentTypeAndOutputMode?.0.isPlay ?? false) { for subscriber in self.isPlaybackActiveSubscribers.copyItems() { @@ -976,6 +973,10 @@ public final class ManagedAudioSession { managedAudioSessionLog("ManagedAudioSession callKitActivatedAudioSession") self.callKitAudioSessionIsActive = true self.updateHolders() + + for subscriber in self.isActiveSubscribers.copyItems() { + subscriber(self.isActiveValue || self.callKitAudioSessionIsActive) + } } } @@ -984,6 +985,10 @@ public final class ManagedAudioSession { managedAudioSessionLog("ManagedAudioSession callKitDeactivatedAudioSession") self.callKitAudioSessionIsActive = false self.updateHolders() + + for subscriber in self.isActiveSubscribers.copyItems() { + subscriber(self.isActiveValue || self.callKitAudioSessionIsActive) + } } } } diff --git a/submodules/TelegramCallsUI/Sources/PresentationCall.swift b/submodules/TelegramCallsUI/Sources/PresentationCall.swift index a5e890f3b6..bfee657104 100644 --- a/submodules/TelegramCallsUI/Sources/PresentationCall.swift +++ b/submodules/TelegramCallsUI/Sources/PresentationCall.swift @@ -888,6 +888,10 @@ public final class PresentationCallImpl: PresentationCall { return self.debugInfoValue.get() } + func video(isIncoming: Bool) -> Signal? { + return self.ongoingContext?.video(isIncoming: isIncoming) + } + public func makeIncomingVideoView(completion: @escaping (PresentationCallVideoView?) -> Void) { self.ongoingContext?.makeIncomingVideoView(completion: { view in if let view = view { diff --git a/submodules/TelegramVoip/Sources/OngoingCallContext.swift b/submodules/TelegramVoip/Sources/OngoingCallContext.swift index 923e197044..5b8e2e0e4a 100644 --- a/submodules/TelegramVoip/Sources/OngoingCallContext.swift +++ b/submodules/TelegramVoip/Sources/OngoingCallContext.swift @@ -1192,6 +1192,31 @@ public final class OngoingCallContext { return (poll |> then(.complete() |> delay(0.5, queue: Queue.concurrentDefaultQueue()))) |> restart } + public func video(isIncoming: Bool) -> Signal { + let queue = self.queue + return Signal { [weak self] subscriber in + let disposable = MetaDisposable() + + queue.async { + guard let strongSelf = self else { + return + } + strongSelf.withContext { context in + if let context = context as? OngoingCallThreadLocalContextWebrtc { + let innerDisposable = context.addVideoOutput(withIsIncoming: isIncoming, sink: { videoFrameData in + subscriber.putNext(OngoingGroupCallContext.VideoFrameData(frameData: videoFrameData)) + }) + disposable.set(ActionDisposable { + innerDisposable.dispose() + }) + } + } + } + + return disposable + } + } + public func makeIncomingVideoView(completion: @escaping (OngoingCallContextPresentationCallVideoView?) -> Void) { self.withContext { context in if let context = context as? OngoingCallThreadLocalContextWebrtc { diff --git a/submodules/TgVoipWebrtc/PublicHeaders/TgVoipWebrtc/OngoingCallThreadLocalContext.h b/submodules/TgVoipWebrtc/PublicHeaders/TgVoipWebrtc/OngoingCallThreadLocalContext.h index 13bf1d4303..734f600161 100644 --- a/submodules/TgVoipWebrtc/PublicHeaders/TgVoipWebrtc/OngoingCallThreadLocalContext.h +++ b/submodules/TgVoipWebrtc/PublicHeaders/TgVoipWebrtc/OngoingCallThreadLocalContext.h @@ -261,6 +261,7 @@ typedef NS_ENUM(int32_t, OngoingCallDataSavingWebrtc) { - (void)setIsMuted:(bool)isMuted; - (void)setIsLowBatteryLevel:(bool)isLowBatteryLevel; - (void)setNetworkType:(OngoingCallNetworkTypeWebrtc)networkType; +- (GroupCallDisposable * _Nonnull)addVideoOutputWithIsIncoming:(bool)isIncoming sink:(void (^_Nonnull)(CallVideoFrameData * _Nonnull))sink; - (void)makeIncomingVideoView:(void (^_Nonnull)(UIView * _Nullable))completion; - (void)requestVideo:(OngoingCallThreadLocalContextVideoCapturer * _Nullable)videoCapturer; - (void)setRequestedVideoAspect:(float)aspect; diff --git a/submodules/TgVoipWebrtc/Sources/OngoingCallThreadLocalContext.mm b/submodules/TgVoipWebrtc/Sources/OngoingCallThreadLocalContext.mm index 3795954fc4..01972c1e7f 100644 --- a/submodules/TgVoipWebrtc/Sources/OngoingCallThreadLocalContext.mm +++ b/submodules/TgVoipWebrtc/Sources/OngoingCallThreadLocalContext.mm @@ -850,6 +850,9 @@ tgcalls::VideoCaptureInterfaceObject *GetVideoCaptureAssumingSameThread(tgcalls: bool _useManualAudioSessionControl; SharedCallAudioDevice *_audioDevice; + int _nextSinkId; + NSMutableDictionary *_sinks; + rtc::scoped_refptr _currentAudioDeviceModule; rtc::Thread *_currentAudioDeviceModuleThread; @@ -1030,6 +1033,8 @@ static void (*InternalVoipLoggingFunction)(NSString *) = NULL; _audioDevice = audioDevice; + _sinks = [[NSMutableDictionary alloc] init]; + _useManualAudioSessionControl = true; [RTCAudioSession sharedInstance].useManualAudio = true; @@ -1469,6 +1474,33 @@ static void (*InternalVoipLoggingFunction)(NSString *) = NULL; } } +- (GroupCallDisposable * _Nonnull)addVideoOutputWithIsIncoming:(bool)isIncoming sink:(void (^_Nonnull)(CallVideoFrameData * _Nonnull))sink { + int sinkId = _nextSinkId; + _nextSinkId += 1; + + GroupCallVideoSink *storedSink = [[GroupCallVideoSink alloc] initWithSink:sink]; + _sinks[@(sinkId)] = storedSink; + + if (_tgVoip) { + if (isIncoming) { + _tgVoip->setIncomingVideoOutput([storedSink sink]); + } + } + + __weak OngoingCallThreadLocalContextWebrtc *weakSelf = self; + id queue = _queue; + return [[GroupCallDisposable alloc] initWithBlock:^{ + [queue dispatch:^{ + __strong OngoingCallThreadLocalContextWebrtc *strongSelf = weakSelf; + if (!strongSelf) { + return; + } + + [strongSelf->_sinks removeObjectForKey:@(sinkId)]; + }]; + }]; +} + - (void)makeIncomingVideoView:(void (^_Nonnull)(UIView * _Nullable))completion { if (_tgVoip) { __weak OngoingCallThreadLocalContextWebrtc *weakSelf = self;