You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

AudioMode.m 3.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. #import "RCTBridgeModule.h"
  2. #import "RCTLog.h"
  3. #import <AVFoundation/AVFoundation.h>
  4. @interface AudioMode : NSObject<RCTBridgeModule>
  5. @end
  6. @implementation AudioMode {
  7. NSString *_category;
  8. NSString *_mode;
  9. }
  10. RCT_EXPORT_MODULE();
  11. typedef enum {
  12. kAudioModeDefault,
  13. kAudioModeAudioCall,
  14. kAudioModeVideoCall
  15. } JitsiMeetAudioMode;
  16. - (NSDictionary *)constantsToExport {
  17. return @{
  18. @"AUDIO_CALL" : [NSNumber numberWithInt: kAudioModeAudioCall],
  19. @"DEFAULT" : [NSNumber numberWithInt: kAudioModeDefault],
  20. @"VIDEO_CALL" : [NSNumber numberWithInt: kAudioModeVideoCall]
  21. };
  22. };
  23. - (instancetype)init {
  24. self = [super init];
  25. if (self) {
  26. _category = nil;
  27. _mode = nil;
  28. }
  29. return self;
  30. }
  31. - (dispatch_queue_t)methodQueue {
  32. // Make sure all our methods run in the main thread. The route change
  33. // notification runs there so this will make sure it will only be fired
  34. // after our changes have been applied (when we cause them, that is).
  35. return dispatch_get_main_queue();
  36. }
  37. - (void)routeChanged:(NSNotification*)notification {
  38. NSInteger reason
  39. = [[notification.userInfo
  40. valueForKey:AVAudioSessionRouteChangeReasonKey]
  41. integerValue];
  42. switch (reason) {
  43. case AVAudioSessionRouteChangeReasonCategoryChange:
  44. // The category has changed. Check if it's the one we want and adjust as
  45. // needed.
  46. [self setCategory:_category mode:_mode error:nil];
  47. break;
  48. default:
  49. // Do nothing.
  50. break;
  51. }
  52. }
  53. - (BOOL)setCategory:(NSString *)category
  54. mode:(NSString *)mode
  55. error:(NSError * _Nullable *)outError {
  56. AVAudioSession *session = [AVAudioSession sharedInstance];
  57. if (session.category != category
  58. && ![session setCategory:category error:outError]) {
  59. RCTLogError(@"Failed to (re)apply specified AVAudioSession category!");
  60. return NO;
  61. }
  62. if (session.mode != mode && ![session setMode:mode error:outError]) {
  63. RCTLogError(@"Failed to (re)apply specified AVAudioSession mode!");
  64. return NO;
  65. }
  66. return YES;
  67. }
  68. RCT_EXPORT_METHOD(setMode:(int)mode
  69. resolve:(RCTPromiseResolveBlock)resolve
  70. reject:(RCTPromiseRejectBlock)reject) {
  71. NSString *avCategory;
  72. NSString *avMode;
  73. NSError *error;
  74. switch (mode) {
  75. case kAudioModeAudioCall:
  76. avCategory = AVAudioSessionCategoryPlayAndRecord;
  77. avMode = AVAudioSessionModeVoiceChat;
  78. break;
  79. case kAudioModeDefault:
  80. avCategory = AVAudioSessionCategorySoloAmbient;
  81. avMode = AVAudioSessionModeDefault;
  82. break;
  83. case kAudioModeVideoCall:
  84. avCategory = AVAudioSessionCategoryPlayAndRecord;
  85. avMode = AVAudioSessionModeVideoChat;
  86. break;
  87. default:
  88. reject(@"setMode", @"Invalid mode", nil);
  89. return;
  90. }
  91. if (![self setCategory:avCategory mode:avMode error:&error] || error) {
  92. reject(@"setMode", error.localizedDescription, error);
  93. return;
  94. }
  95. // Even though the specified category and mode were successfully set, the
  96. // AVAudioSession is a singleton and other parts of the application such as
  97. // WebRTC may undo the settings. Make sure that the settings are reapplied
  98. // upon undoes.
  99. if (!_category || !_mode) {
  100. [[NSNotificationCenter defaultCenter]
  101. addObserver:self
  102. selector:@selector(routeChanged:)
  103. name:AVAudioSessionRouteChangeNotification
  104. object:nil];
  105. }
  106. // Save the desired/specified category and mode so that they may be
  107. // reapplied (upon undoes as described above).
  108. _category = avCategory;
  109. _mode = avMode;
  110. resolve(nil);
  111. }
  112. @end