Make sure changes to audio and video tracks are correctly dispatched

Signed-off-by: Marcel Müller <marcel-mueller@gmx.de>
This commit is contained in:
Marcel Müller 2023-02-15 16:42:15 +01:00
Родитель 7142b42f75
Коммит c8759088f1
3 изменённых файлов: 148 добавлений и 108 удалений

Просмотреть файл

@ -386,9 +386,13 @@ typedef void (^UpdateCallParticipantViewCellBlock)(CallParticipantViewCell *cell
-(void)appWillResignActive:(NSNotification*)notification
{
if (!_isAudioOnly && _callController && [_callController isVideoEnabled]) {
// Disable video when the app moves to the background as we can't access the camera anymore.
[self disableLocalVideo];
if (!_isAudioOnly && _callController) {
[_callController getVideoEnabledStateWithCompletionBlock:^(BOOL isEnabled) {
if (isEnabled) {
// Disable video when the app moves to the background as we can't access the camera anymore.
[self disableLocalVideo];
}
}];
}
}
@ -423,11 +427,7 @@ typedef void (^UpdateCallParticipantViewCellBlock)(CallParticipantViewCell *cell
}
BOOL isMuted = [[notification.userInfo objectForKey:@"isMuted"] boolValue];
if (isMuted) {
[self muteAudio];
} else {
[self unmuteAudio];
}
[self setAudioMuted:isMuted];
}
- (void)providerDidEndCall:(NSNotification *)notification
@ -1030,18 +1030,26 @@ typedef void (^UpdateCallParticipantViewCellBlock)(CallParticipantViewCell *cell
- (void)pushToTalkStart
{
if (_callController && ![_callController isAudioEnabled]) {
[self unmuteAudio];
[_buttonFeedbackGenerator impactOccurred];
_pushToTalkActive = YES;
if (!_callController) {
return;
}
[_callController getAudioEnabledStateWithCompletionBlock:^(BOOL isEnabled) {
if (!isEnabled) {
[self setAudioMuted:NO];
dispatch_async(dispatch_get_main_queue(), ^{
[self->_buttonFeedbackGenerator impactOccurred];
self->_pushToTalkActive = YES;
});
}
}];
}
- (void)pushToTalkEnd
{
if (_pushToTalkActive) {
[self muteAudio];
[self setAudioMuted:YES];
_pushToTalkActive = NO;
}
@ -1049,26 +1057,24 @@ typedef void (^UpdateCallParticipantViewCellBlock)(CallParticipantViewCell *cell
- (IBAction)audioButtonPressed:(id)sender
{
if (!_callController) {return;}
if ([_callController isAudioEnabled]) {
if ([CallKitManager isCallKitAvailable]) {
[[CallKitManager sharedInstance] changeAudioMuted:YES forCall:_room.token];
} else {
[self muteAudio];
}
} else {
if ([CallKitManager isCallKitAvailable]) {
[[CallKitManager sharedInstance] changeAudioMuted:NO forCall:_room.token];
} else {
[self unmuteAudio];
}
if (!_callController) {
return;
}
[_callController getAudioEnabledStateWithCompletionBlock:^(BOOL isEnabled) {
if ([CallKitManager isCallKitAvailable]) {
dispatch_async(dispatch_get_main_queue(), ^{
[[CallKitManager sharedInstance] changeAudioMuted:isEnabled forCall:self->_room.token];
});
} else {
[self setAudioMuted:isEnabled];
}
}];
}
- (void)forceMuteAudio
{
[self muteAudio];
[self setAudioMuted:YES];
NSString *micDisabledString = NSLocalizedString(@"Microphone disabled", nil);
NSString *forceMutedString = NSLocalizedString(@"You have been muted by a moderator", nil);
@ -1079,51 +1085,43 @@ typedef void (^UpdateCallParticipantViewCellBlock)(CallParticipantViewCell *cell
});
}
- (void)muteAudio
- (void)setAudioMuted:(BOOL)isMuted
{
[_callController enableAudio:NO];
[self setAudioMuteButtonActive:NO];
}
- (void)unmuteAudio
{
[_callController enableAudio:YES];
[self setAudioMuteButtonActive:YES];
[_callController enableAudio:!isMuted];
[self setAudioMuteButtonActive:!isMuted];
}
- (IBAction)videoButtonPressed:(id)sender
{
if (!_callController) {return;}
if ([_callController isVideoEnabled]) {
[self disableLocalVideo];
_userDisabledVideo = YES;
} else {
[self enableLocalVideo];
_userDisabledVideo = NO;
if (!_callController) {
return;
}
[_callController getVideoEnabledStateWithCompletionBlock:^(BOOL isEnabled) {
[self setLocalVideoEnabled:!isEnabled];
self->_userDisabledVideo = isEnabled;
}];
}
- (void)disableLocalVideo
{
[_callController enableVideo:NO];
[self setLocalVideoViewHidden:YES];
[self setVideoDisableButtonActive:NO];
[self setLocalVideoEnabled:NO];
}
- (void)enableLocalVideo
{
[_callController enableVideo:YES];
[self setLocalVideoViewHidden:NO];
[self setVideoDisableButtonActive:YES];
[self setLocalVideoEnabled:YES];
}
- (void)setLocalVideoEnabled:(BOOL)enabled
{
[_callController enableVideo:enabled];
[self setLocalVideoViewHidden:!enabled];
[self setVideoDisableButtonActive:enabled];
}
- (IBAction)switchCameraButtonPressed:(id)sender
{
[self switchCamera];
}
- (void)switchCamera
{
[_callController switchCamera];
[self flipLocalVideoView];

Просмотреть файл

@ -30,6 +30,9 @@
@class RTCVideoTrack;
@class RTCCameraVideoCapturer;
typedef void (^GetVideoEnabledStateCompletionBlock)(BOOL isEnabled);
typedef void (^GetAudioEnabledStateCompletionBlock)(BOOL isEnabled);
@protocol NCCallControllerDelegate<NSObject>
- (void)callControllerDidJoinCall:(NCCallController *)callController;
@ -70,8 +73,8 @@
- (instancetype)initWithDelegate:(id<NCCallControllerDelegate>)delegate inRoom:(NCRoom *)room forAudioOnlyCall:(BOOL)audioOnly withSessionId:(NSString *)sessionId andVoiceChatMode:(BOOL)voiceChatMode;
- (void)startCall;
- (void)leaveCall;
- (BOOL)isVideoEnabled;
- (BOOL)isAudioEnabled;
- (void)getVideoEnabledStateWithCompletionBlock:(GetVideoEnabledStateCompletionBlock)block;
- (void)getAudioEnabledStateWithCompletionBlock:(GetAudioEnabledStateCompletionBlock)block;
- (void)switchCamera;
- (void)enableVideo:(BOOL)enable;
- (void)enableAudio:(BOOL)enable;

Просмотреть файл

@ -264,16 +264,18 @@ static NSString * const kNCVideoTrackKind = @"video";
{
NSLog(@"willSwitchToCall");
BOOL isAudioEnabled = [self isAudioEnabled];
BOOL isVideoEnabled = [self isVideoEnabled];
[[WebRTCCommon shared] dispatch:^{
BOOL isAudioEnabled = [self isAudioEnabled];
BOOL isVideoEnabled = [self isVideoEnabled];
[self stopCallController];
[self stopCallController];
[self leaveCallInServerWithCompletionBlock:^(NSError *error) {
if (error) {
NSLog(@"Could not leave call. Error: %@", error.description);
}
[self.delegate callController:self isSwitchingToCall:token withAudioEnabled:isAudioEnabled andVideoEnabled:isVideoEnabled];
[self leaveCallInServerWithCompletionBlock:^(NSError *error) {
if (error) {
NSLog(@"Could not leave call. Error: %@", error.description);
}
[self.delegate callController:self isSwitchingToCall:token withAudioEnabled:isAudioEnabled andVideoEnabled:isVideoEnabled];
}];
}];
}
@ -318,14 +320,13 @@ static NSString * const kNCVideoTrackKind = @"video";
[[WebRTCCommon shared] dispatch:^{
[self cleanCurrentPeerConnections];
[self->_localVideoCapturer stopCapture];
self->_localVideoCapturer = nil;
self->_localAudioTrack = nil;
self->_localVideoTrack = nil;
self->_connectionsDict = nil;
}];
[_localVideoCapturer stopCapture];
_localVideoCapturer = nil;
_localAudioTrack = nil;
_localVideoTrack = nil;
_connectionsDict = nil;
[self stopMonitoringMicrophoneAudioLevel];
[_signalingController stopAllRequests];
@ -371,40 +372,68 @@ static NSString * const kNCVideoTrackKind = @"video";
- (BOOL)isVideoEnabled
{
[[WebRTCCommon shared] assertQueue];
return _localVideoTrack ? _localVideoTrack.isEnabled : NO;
}
- (BOOL)isAudioEnabled
{
[[WebRTCCommon shared] assertQueue];
return _localAudioTrack ? _localAudioTrack.isEnabled : NO;
}
- (void)getVideoEnabledStateWithCompletionBlock:(GetAudioEnabledStateCompletionBlock)block
{
[[WebRTCCommon shared] dispatch:^{
if (block) {
block([self isVideoEnabled]);
}
}];
}
- (void)getAudioEnabledStateWithCompletionBlock:(GetAudioEnabledStateCompletionBlock)block
{
[[WebRTCCommon shared] dispatch:^{
if (block) {
block([self isAudioEnabled]);
}
}];
}
- (void)switchCamera
{
[_localVideoCaptureController switchCamera];
[[WebRTCCommon shared] dispatch:^{
[self->_localVideoCaptureController switchCamera];
}];
}
- (void)enableVideo:(BOOL)enable
{
if (enable) {
[_localVideoCaptureController startCapture];
} else {
[_localVideoCaptureController stopCapture];
}
[_localVideoTrack setIsEnabled:enable];
[self sendDataChannelMessageToAllOfType:enable ? @"videoOn" : @"videoOff" withPayload:nil];
[[WebRTCCommon shared] dispatch:^{
if (enable) {
[self->_localVideoCaptureController startCapture];
} else {
[self->_localVideoCaptureController stopCapture];
}
[self->_localVideoTrack setIsEnabled:enable];
[self sendDataChannelMessageToAllOfType:enable ? @"videoOn" : @"videoOff" withPayload:nil];
}];
}
- (void)enableAudio:(BOOL)enable
{
[_localAudioTrack setIsEnabled:enable];
[self sendDataChannelMessageToAllOfType:enable ? @"audioOn" : @"audioOff" withPayload:nil];
[[WebRTCCommon shared] dispatch:^{
[self->_localAudioTrack setIsEnabled:enable];
[self sendDataChannelMessageToAllOfType:enable ? @"audioOn" : @"audioOff" withPayload:nil];
if (!enable) {
_speaking = NO;
[self sendDataChannelMessageToAllOfType:@"stoppedSpeaking" withPayload:nil];
}
if (!enable) {
self->_speaking = NO;
[self sendDataChannelMessageToAllOfType:@"stoppedSpeaking" withPayload:nil];
}
}];
}
- (void)raiseHand:(BOOL)raised
@ -571,17 +600,20 @@ static NSString * const kNCVideoTrackKind = @"video";
- (void)checkMicAudioLevel
{
if ([self isAudioEnabled]) {
[_recorder updateMeters];
float averagePower = [_recorder averagePowerForChannel:0];
if (averagePower >= -50.0f && !_speaking) {
_speaking = YES;
[self sendDataChannelMessageToAllOfType:@"speaking" withPayload:nil];
} else if (averagePower < -50.0f && _speaking) {
_speaking = NO;
[self sendDataChannelMessageToAllOfType:@"stoppedSpeaking" withPayload:nil];
[[WebRTCCommon shared] dispatch:^{
if ([self isAudioEnabled]) {
[self->_recorder updateMeters];
float averagePower = [self->_recorder averagePowerForChannel:0];
if (averagePower >= -50.0f && !self->_speaking) {
self->_speaking = YES;
[self sendDataChannelMessageToAllOfType:@"speaking" withPayload:nil];
} else if (averagePower < -50.0f && self->_speaking) {
self->_speaking = NO;
[self sendDataChannelMessageToAllOfType:@"stoppedSpeaking" withPayload:nil];
}
}
}
}];
}
#pragma mark - Call participants
@ -603,6 +635,8 @@ static NSString * const kNCVideoTrackKind = @"video";
- (void)createLocalAudioTrack
{
[[WebRTCCommon shared] assertQueue];
RTCPeerConnectionFactory *peerConnectionFactory = [WebRTCCommon shared].peerConnectionFactory;
RTCAudioSource *source = [peerConnectionFactory audioSourceWithConstraints:nil];
_localAudioTrack = [peerConnectionFactory audioTrackWithSource:source trackId:kNCAudioTrackId];
@ -616,6 +650,8 @@ static NSString * const kNCVideoTrackKind = @"video";
- (void)createLocalVideoTrack
{
[[WebRTCCommon shared] assertQueue];
#if !TARGET_IPHONE_SIMULATOR
RTCPeerConnectionFactory *peerConnectionFactory = [WebRTCCommon shared].peerConnectionFactory;
RTCVideoSource *source = [peerConnectionFactory videoSource];
@ -713,16 +749,16 @@ static NSString * const kNCVideoTrackKind = @"video";
- (void)sendDataChannelMessageToAllOfType:(NSString *)type withPayload:(id)payload
{
[[WebRTCCommon shared] dispatch:^{
if ([self->_externalSignalingController hasMCU]) {
[self->_publisherPeerConnection sendDataChannelMessageOfType:type withPayload:payload];
} else {
NSArray *connectionWrappers = [self.connectionsDict allValues];
for (NCPeerConnection *peerConnection in connectionWrappers) {
[peerConnection sendDataChannelMessageOfType:type withPayload:payload];
}
[[WebRTCCommon shared] assertQueue];
if ([self->_externalSignalingController hasMCU]) {
[self->_publisherPeerConnection sendDataChannelMessageOfType:type withPayload:payload];
} else {
NSArray *connectionWrappers = [self.connectionsDict allValues];
for (NCPeerConnection *peerConnection in connectionWrappers) {
[peerConnection sendDataChannelMessageOfType:type withPayload:payload];
}
}];
}
}
#pragma mark - External signaling support
@ -763,7 +799,10 @@ static NSString * const kNCVideoTrackKind = @"video";
@"userid":_account.userId,
@"name":_account.userDisplayName
};
[self sendDataChannelMessageToAllOfType:@"nickChanged" withPayload:payload];
[[WebRTCCommon shared] dispatch:^{
[self sendDataChannelMessageToAllOfType:@"nickChanged" withPayload:payload];
}];
}
- (void)startSendingNick