Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

AudioMode.m 4.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. /*
  2. * Copyright @ 2017-present Atlassian Pty Ltd
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #import <AVFoundation/AVFoundation.h>
  17. #import <React/RCTBridgeModule.h>
  18. #import <React/RCTLog.h>
  19. @interface AudioMode : NSObject<RCTBridgeModule>
  20. @end
  21. @implementation AudioMode {
  22. NSString *_category;
  23. NSString *_mode;
  24. }
  25. RCT_EXPORT_MODULE();
  26. typedef enum {
  27. kAudioModeDefault,
  28. kAudioModeAudioCall,
  29. kAudioModeVideoCall
  30. } JitsiMeetAudioMode;
  31. + (BOOL)requiresMainQueueSetup {
  32. return NO;
  33. }
  34. - (NSDictionary *)constantsToExport {
  35. return @{
  36. @"AUDIO_CALL" : [NSNumber numberWithInt: kAudioModeAudioCall],
  37. @"DEFAULT" : [NSNumber numberWithInt: kAudioModeDefault],
  38. @"VIDEO_CALL" : [NSNumber numberWithInt: kAudioModeVideoCall]
  39. };
  40. };
  41. - (instancetype)init {
  42. self = [super init];
  43. if (self) {
  44. _category = nil;
  45. _mode = nil;
  46. }
  47. return self;
  48. }
  49. - (dispatch_queue_t)methodQueue {
  50. // Make sure all our methods run in the main thread. The route change
  51. // notification runs there so this will make sure it will only be fired
  52. // after our changes have been applied (when we cause them, that is).
  53. return dispatch_get_main_queue();
  54. }
  55. - (void)routeChanged:(NSNotification*)notification {
  56. NSInteger reason
  57. = [[notification.userInfo
  58. valueForKey:AVAudioSessionRouteChangeReasonKey]
  59. integerValue];
  60. switch (reason) {
  61. case AVAudioSessionRouteChangeReasonCategoryChange:
  62. // The category has changed. Check if it's the one we want and adjust as
  63. // needed.
  64. [self setCategory:_category mode:_mode error:nil];
  65. break;
  66. default:
  67. // Do nothing.
  68. break;
  69. }
  70. }
  71. - (BOOL)setCategory:(NSString *)category
  72. mode:(NSString *)mode
  73. error:(NSError * _Nullable *)outError {
  74. AVAudioSession *session = [AVAudioSession sharedInstance];
  75. if (session.category != category
  76. && ![session setCategory:category error:outError]) {
  77. RCTLogError(@"Failed to (re)apply specified AVAudioSession category!");
  78. return NO;
  79. }
  80. if (session.mode != mode && ![session setMode:mode error:outError]) {
  81. RCTLogError(@"Failed to (re)apply specified AVAudioSession mode!");
  82. return NO;
  83. }
  84. return YES;
  85. }
  86. RCT_EXPORT_METHOD(setMode:(int)mode
  87. resolve:(RCTPromiseResolveBlock)resolve
  88. reject:(RCTPromiseRejectBlock)reject) {
  89. NSString *avCategory;
  90. NSString *avMode;
  91. NSError *error;
  92. switch (mode) {
  93. case kAudioModeAudioCall:
  94. avCategory = AVAudioSessionCategoryPlayAndRecord;
  95. avMode = AVAudioSessionModeVoiceChat;
  96. break;
  97. case kAudioModeDefault:
  98. avCategory = AVAudioSessionCategorySoloAmbient;
  99. avMode = AVAudioSessionModeDefault;
  100. break;
  101. case kAudioModeVideoCall:
  102. avCategory = AVAudioSessionCategoryPlayAndRecord;
  103. avMode = AVAudioSessionModeVideoChat;
  104. break;
  105. default:
  106. reject(@"setMode", @"Invalid mode", nil);
  107. return;
  108. }
  109. if (![self setCategory:avCategory mode:avMode error:&error] || error) {
  110. reject(@"setMode", error.localizedDescription, error);
  111. return;
  112. }
  113. // Even though the specified category and mode were successfully set, the
  114. // AVAudioSession is a singleton and other parts of the application such as
  115. // WebRTC may undo the settings. Make sure that the settings are reapplied
  116. // upon undoes.
  117. if (!_category || !_mode) {
  118. [[NSNotificationCenter defaultCenter]
  119. addObserver:self
  120. selector:@selector(routeChanged:)
  121. name:AVAudioSessionRouteChangeNotification
  122. object:nil];
  123. }
  124. // Save the desired/specified category and mode so that they may be
  125. // reapplied (upon undoes as described above).
  126. _category = avCategory;
  127. _mode = avMode;
  128. resolve(nil);
  129. }
  130. @end