From 7ce7715b45f962473019b8632ce99912765d954a Mon Sep 17 00:00:00 2001 From: Jhen Date: Sat, 30 Sep 2023 12:48:10 +0800 Subject: [PATCH] feat(ios): implement AudioSession utils --- ios/RNWhisper.mm | 64 +++++++++++++++++++ ios/RNWhisper.xcodeproj/project.pbxproj | 6 ++ ios/RNWhisperAudioSessionUtils.h | 13 ++++ ios/RNWhisperAudioSessionUtils.m | 84 +++++++++++++++++++++++++ 4 files changed, 167 insertions(+) create mode 100644 ios/RNWhisperAudioSessionUtils.h create mode 100644 ios/RNWhisperAudioSessionUtils.m diff --git a/ios/RNWhisper.mm b/ios/RNWhisper.mm index 95bfaf3..072145d 100644 --- a/ios/RNWhisper.mm +++ b/ios/RNWhisper.mm @@ -1,6 +1,7 @@ #import "RNWhisper.h" #import "RNWhisperContext.h" #import "RNWhisperDownloader.h" +#import "RNWhisperAudioSessionUtils.h" #include #include @@ -283,6 +284,69 @@ - (void)invalidate { [RNWhisperDownloader clearCache]; } +// MARK: - AudioSessionUtils + +RCT_EXPORT_METHOD(getAudioSessionCurrentCategory:(RCTPromiseResolveBlock)resolve + withRejecter:(RCTPromiseRejectBlock)reject) +{ + NSString *category = [RNWhisperAudioSessionUtils getCurrentCategory]; + NSArray *options = [RNWhisperAudioSessionUtils getCurrentOptions]; + resolve(@{ + @"category": category, + @"options": options + }); +} + +RCT_EXPORT_METHOD(getAudioSessionCurrentMode:(RCTPromiseResolveBlock)resolve + withRejecter:(RCTPromiseRejectBlock)reject) +{ + NSString *mode = [RNWhisperAudioSessionUtils getCurrentMode]; + resolve(mode); +} + +RCT_REMAP_METHOD(setAudioSessionCategory, + withCategory:(NSString *)category + withOptions:(NSArray *)options + withResolver:(RCTPromiseResolveBlock)resolve + withRejecter:(RCTPromiseRejectBlock)reject) +{ + NSError *error = nil; + [RNWhisperAudioSessionUtils setCategory:category options:options error:&error]; + if (error != nil) { + reject(@"whisper_error", [NSString stringWithFormat:@"Failed to set category. Error: %@", error], nil); + return; + } + resolve(nil); +} + +RCT_REMAP_METHOD(setAudioSessionMode, + withMode:(NSString *)mode + withResolver:(RCTPromiseResolveBlock)resolve + withRejecter:(RCTPromiseRejectBlock)reject) +{ + NSError *error = nil; + [RNWhisperAudioSessionUtils setMode:mode error:&error]; + if (error != nil) { + reject(@"whisper_error", [NSString stringWithFormat:@"Failed to set mode. Error: %@", error], nil); + return; + } + resolve(nil); +} + +RCT_REMAP_METHOD(setAudioSessionActive, + withActive:(BOOL)active + withResolver:(RCTPromiseResolveBlock)resolve + withRejecter:(RCTPromiseRejectBlock)reject) +{ + NSError *error = nil; + [RNWhisperAudioSessionUtils setActive:active error:&error]; + if (error != nil) { + reject(@"whisper_error", [NSString stringWithFormat:@"Failed to set active. Error: %@", error], nil); + return; + } + resolve(nil); +} + #ifdef RCT_NEW_ARCH_ENABLED - (std::shared_ptr)getTurboModule: (const facebook::react::ObjCTurboModule::InitParams &)params diff --git a/ios/RNWhisper.xcodeproj/project.pbxproj b/ios/RNWhisper.xcodeproj/project.pbxproj index b6610ad..4b8c527 100644 --- a/ios/RNWhisper.xcodeproj/project.pbxproj +++ b/ios/RNWhisper.xcodeproj/project.pbxproj @@ -8,6 +8,7 @@ /* Begin PBXBuildFile section */ 5E555C0D2413F4C50049A1A2 /* RNWhisper.mm in Sources */ = {isa = PBXBuildFile; fileRef = B3E7B5891CC2AC0600A0062D /* RNWhisper.mm */; }; + 7F458E922AC7DC74007045F6 /* RNWhisperAudioSessionUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 7F458E912AC7DC74007045F6 /* RNWhisperAudioSessionUtils.m */; }; 7FE0BBA12ABE6C7B0049B4E4 /* RNWhisperDownloader.m in Sources */ = {isa = PBXBuildFile; fileRef = 7FE0BB9B2ABE6C7B0049B4E4 /* RNWhisperDownloader.m */; }; 7FE0BBA22ABE6C7B0049B4E4 /* RNWhisperAudioUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 7FE0BB9C2ABE6C7B0049B4E4 /* RNWhisperAudioUtils.m */; }; 7FE0BBA32ABE6C7B0049B4E4 /* RNWhisperContext.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7FE0BBA02ABE6C7B0049B4E4 /* RNWhisperContext.mm */; }; @@ -27,6 +28,8 @@ /* Begin PBXFileReference section */ 134814201AA4EA6300B7C361 /* libRNWhisper.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRNWhisper.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 7F458E902AC7DC74007045F6 /* RNWhisperAudioSessionUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNWhisperAudioSessionUtils.h; sourceTree = ""; }; + 7F458E912AC7DC74007045F6 /* RNWhisperAudioSessionUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNWhisperAudioSessionUtils.m; sourceTree = ""; }; 7FE0BB9A2ABE6C7B0049B4E4 /* RNWhisper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNWhisper.h; sourceTree = ""; }; 7FE0BB9B2ABE6C7B0049B4E4 /* RNWhisperDownloader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNWhisperDownloader.m; sourceTree = ""; }; 7FE0BB9C2ABE6C7B0049B4E4 /* RNWhisperAudioUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNWhisperAudioUtils.m; sourceTree = ""; }; @@ -59,6 +62,8 @@ 58B511D21A9E6C8500147676 = { isa = PBXGroup; children = ( + 7F458E902AC7DC74007045F6 /* RNWhisperAudioSessionUtils.h */, + 7F458E912AC7DC74007045F6 /* RNWhisperAudioSessionUtils.m */, 7FE0BB9F2ABE6C7B0049B4E4 /* RNWhisperAudioUtils.h */, 7FE0BB9C2ABE6C7B0049B4E4 /* RNWhisperAudioUtils.m */, 7FE0BB9A2ABE6C7B0049B4E4 /* RNWhisper.h */, @@ -132,6 +137,7 @@ 7FE0BBA22ABE6C7B0049B4E4 /* RNWhisperAudioUtils.m in Sources */, 7FE0BBA32ABE6C7B0049B4E4 /* RNWhisperContext.mm in Sources */, 7FE0BBA12ABE6C7B0049B4E4 /* RNWhisperDownloader.m in Sources */, + 7F458E922AC7DC74007045F6 /* RNWhisperAudioSessionUtils.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/ios/RNWhisperAudioSessionUtils.h b/ios/RNWhisperAudioSessionUtils.h new file mode 100644 index 0000000..9ab0d38 --- /dev/null +++ b/ios/RNWhisperAudioSessionUtils.h @@ -0,0 +1,13 @@ +#import +#import + +@interface RNWhisperAudioSessionUtils : NSObject + ++(NSString *)getCurrentCategory; ++(NSArray *)getCurrentOptions; ++(NSString *)getCurrentMode; ++(void)setCategory:(NSString *)category options:(NSArray *)options error:(NSError **)error; ++(void)setMode:(NSString *)mode error:(NSError **)error; ++(void)setActive:(BOOL)active error:(NSError **)error; + +@end diff --git a/ios/RNWhisperAudioSessionUtils.m b/ios/RNWhisperAudioSessionUtils.m new file mode 100644 index 0000000..c0578ad --- /dev/null +++ b/ios/RNWhisperAudioSessionUtils.m @@ -0,0 +1,84 @@ +#import "RNWhisperAudioSessionUtils.h" + +@implementation RNWhisperAudioSessionUtils + +static NSDictionary *_categories; +static NSDictionary *_options; +static NSDictionary *_modes; + ++ (void)initialize { + _categories = @{ + @"Ambient": AVAudioSessionCategoryAmbient, + @"SoloAmbient": AVAudioSessionCategorySoloAmbient, + @"Playback": AVAudioSessionCategoryPlayback, + @"Record": AVAudioSessionCategoryRecord, + @"PlayAndRecord": AVAudioSessionCategoryPlayAndRecord, + @"MultiRoute": AVAudioSessionCategoryMultiRoute + }; + _options = @{ + @"MixWithOthers": @(AVAudioSessionCategoryOptionMixWithOthers), + @"DuckOthers": @(AVAudioSessionCategoryOptionDuckOthers), + @"InterruptSpokenAudioAndMixWithOthers": @(AVAudioSessionCategoryOptionInterruptSpokenAudioAndMixWithOthers), + @"AllowBluetooth": @(AVAudioSessionCategoryOptionAllowBluetooth), + @"AllowBluetoothA2DP": @(AVAudioSessionCategoryOptionAllowBluetoothA2DP), + @"AllowAirPlay": @(AVAudioSessionCategoryOptionAllowAirPlay), + @"DefaultToSpeaker": @(AVAudioSessionCategoryOptionDefaultToSpeaker) + }; + _modes = @{ + @"Default": AVAudioSessionModeDefault, + @"VoiceChat": AVAudioSessionModeVoiceChat, + @"VideoChat": AVAudioSessionModeVideoChat, + @"GameChat": AVAudioSessionModeGameChat, + @"VideoRecording": AVAudioSessionModeVideoRecording, + @"Measurement": AVAudioSessionModeMeasurement, + @"MoviePlayback": AVAudioSessionModeMoviePlayback, + @"SpokenAudio": AVAudioSessionModeSpokenAudio + }; +} + ++(NSString *)getCurrentCategory { + AVAudioSession *session = [AVAudioSession sharedInstance]; + return session.category; +} + ++(NSArray *)getCurrentOptions { + AVAudioSession *session = [AVAudioSession sharedInstance]; + AVAudioSessionCategoryOptions options = session.categoryOptions; + NSMutableArray *result = [NSMutableArray array]; + for (NSString *key in _options) { + if ((options & [[_options objectForKey:key] unsignedIntegerValue]) != 0) { + [result addObject:key]; + } + } + return result; +} + ++(NSString *)getCurrentMode { + AVAudioSession *session = [AVAudioSession sharedInstance]; + return session.mode; +} + ++(void)setCategory:(NSString *)category options:(NSArray *)options error:(NSError **)error { + AVAudioSession *session = [AVAudioSession sharedInstance]; + [session setCategory:[_categories objectForKey:category] withOptions:[self getOptions:options] error:error]; +} + ++(void)setMode:(NSString *)mode error:(NSError **)error { + AVAudioSession *session = [AVAudioSession sharedInstance]; + [session setMode:[_modes objectForKey:mode] error:error]; +} + ++(void)setActive:(BOOL)active error:(NSError **)error { + AVAudioSession *session = [AVAudioSession sharedInstance]; + [session setActive:active error:error]; +} + ++(AVAudioSessionCategoryOptions)getOptions:(NSArray *)options { + AVAudioSessionCategoryOptions result = 0; + for (NSString *option in options) { + result |= [[_options objectForKey:option] unsignedIntegerValue]; + } + return result; +} + +@end \ No newline at end of file