From 0213f991869ea8dc60b608e4da980c3a45c90996 Mon Sep 17 00:00:00 2001 From: parveshneedhoo Date: Fri, 25 Aug 2023 16:15:28 +0400 Subject: [PATCH 1/5] setup audio sessionand take image when change is detected --- plugin.xml | 1 - src/ios/CDVVolumeButtons.m | 157 ++++++++++++++++++++++++++++++------- 2 files changed, 128 insertions(+), 30 deletions(-) diff --git a/plugin.xml b/plugin.xml index 293c395..4367ca1 100644 --- a/plugin.xml +++ b/plugin.xml @@ -11,6 +11,5 @@ - diff --git a/src/ios/CDVVolumeButtons.m b/src/ios/CDVVolumeButtons.m index 98099bf..34c4aa3 100644 --- a/src/ios/CDVVolumeButtons.m +++ b/src/ios/CDVVolumeButtons.m @@ -1,65 +1,164 @@ #import #import "MediaPlayer/MPVolumeView.h" -#import +#import @interface CDVVolumeButtons : CDVPlugin { // Member variables go here. } -- (void)onPause; -- (void)onResume; -- (void)start:(CDVInvokedUrlCommand*)command; -- (void)stop:(CDVInvokedUrlCommand*)command; -@property (strong, nonatomic) JPSVolumeButtonHandler *volumeButtonHandler; +@property (nonatomic, strong) MPVolumeView *volumeView; +@property (nonatomic, strong) AVAudioSession *session; +@property (nonatomic, strong) NSString *sessionCategory; +@property (nonatomic, assign) float userVolume; +@property (nonatomic, assign) bool isAdjustingInitialVolume; +@property (nonatomic, assign) bool appIsActive; +@property (nonatomic, assign) AVAudioSessionCategoryOptions sessionOptions; +@property (nonatomic) NSString *onVolumeButtonPressedHandlerId; @end @implementation CDVVolumeButtons +static void *sessionContext = &sessionContext; + - (void)onPause { [self runBlockWithTryCatch:^{ - // Set session category to multi route as multiple volume/audio streams can be active at the same time - self.volumeButtonHandler.sessionCategory = AVAudioSessionCategoryMultiRoute; - [self.volumeButtonHandler stopHandler]; + [self setSystemVolume:self.userVolume]; + self.appIsActive = NO; + [self.session removeObserver:self forKeyPath:@"outputVolume"]; }]; } - (void)onResume { [self runBlockWithTryCatch:^{ - // Set session category to playback as it is the default used by JPSVolumeButtonHandler - self.volumeButtonHandler.sessionCategory = AVAudioSessionCategoryPlayback; - [self.volumeButtonHandler startHandler:YES]; + [self setupAudioSession]; + [self setVolume]; }]; } - (void)start:(CDVInvokedUrlCommand*)command { [self runBlockWithTryCatch:^{ + self.onVolumeButtonPressedHandlerId = command.callbackId; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onPause) name:UIApplicationDidEnterBackgroundNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onResume) name:UIApplicationWillEnterForegroundNotification object:nil]; - if (self.volumeButtonHandler == nil) { - self.volumeButtonHandler = [JPSVolumeButtonHandler volumeButtonHandlerWithUpBlock:^{ - CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; - [pluginResult setKeepCallback:@YES]; - [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; - } downBlock:^{ - CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; - [pluginResult setKeepCallback:@YES]; - [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; - }]; - } - // Set session category to playback as it is the default used by JPSVolumeButtonHandler - self.volumeButtonHandler.sessionCategory = AVAudioSessionCategoryPlayback; - [self.volumeButtonHandler startHandler:YES]; + + [self setupAudioSession]; + self.userVolume = self.session.outputVolume; + [self setVolume]; }]; } - (void)stop:(CDVInvokedUrlCommand*)command { [self runBlockWithTryCatch:^{ - // Set session category to multi route as multiple volume/audio streams can be active at the same time - self.volumeButtonHandler.sessionCategory = AVAudioSessionCategoryMultiRoute; - [self.volumeButtonHandler stopHandler]; + [self.session removeObserver:self forKeyPath:@"outputVolume"]; + [[NSNotificationCenter defaultCenter] removeObserver:self]; }]; } +- (void)setupAudioSession { + self.sessionCategory = AVAudioSessionCategoryPlayback; + self.sessionOptions = AVAudioSessionCategoryOptionMixWithOthers; + self.volumeView = [[MPVolumeView alloc] initWithFrame:CGRectMake(MAXFLOAT, MAXFLOAT, 0, 0)]; + + [[UIApplication sharedApplication].windows.firstObject addSubview:self.volumeView]; + + self.volumeView.hidden = NO; + self.session = [AVAudioSession sharedInstance]; + NSError *error = nil; + [self.session setCategory:self.sessionCategory + withOptions:self.sessionOptions + error:&error]; + [self.session setActive:YES error:&error]; + [self.session addObserver:self + forKeyPath:@"outputVolume" + options:(NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew) + context:sessionContext]; + self.appIsActive = YES; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(audioSessionInterrupted:) + name:AVAudioSessionInterruptionNotification + object:nil]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(applicationDidChangeActive:) + name:UIApplicationWillResignActiveNotification + object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(applicationDidChangeActive:) + name:UIApplicationDidBecomeActiveNotification + object:nil]; +} + +- (void)audioSessionInterrupted:(NSNotification*)notification { + NSDictionary *interuptionDict = notification.userInfo; + NSInteger interuptionType = [[interuptionDict valueForKey:AVAudioSessionInterruptionTypeKey] integerValue]; + switch (interuptionType) { + case AVAudioSessionInterruptionTypeBegan: + NSLog(@"Audio Session Interruption case started.", nil); + break; + case AVAudioSessionInterruptionTypeEnded: + { + NSLog(@"Audio Session Interruption case ended.", nil); + NSError *error = nil; + [self.session setActive:YES error:&error]; + if (error) { + NSLog(@"%@", error); + } + break; + } + default: + NSLog(@"Audio Session Interruption Notification case default.", nil); + break; + } +} + +- (void)applicationDidChangeActive:(NSNotification *)notification { + self.appIsActive = [notification.name isEqualToString:UIApplicationDidBecomeActiveNotification]; + if (self.appIsActive ) { + [self setVolume]; + } +} + +- (void)setVolume { + float currentVolume = self.session.outputVolume; + + if (currentVolume >= 0.80000 || currentVolume <= 0.20000) { + self.isAdjustingInitialVolume = true; + [self setSystemVolume:0.50000]; + } +} + +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { + if (context == sessionContext) { + if (!self.appIsActive) { + // Probably control center, skip blocks + return; + } + if (self.isAdjustingInitialVolume) { + self.isAdjustingInitialVolume = false; + [self setVolume]; + return; + } + [self takeImage]; + [self setVolume]; + } else { + [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; + } +} + +- (void)takeImage { + [self runBlockWithTryCatch:^{ + CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; + [pluginResult setKeepCallback:@YES]; + [self.commandDelegate sendPluginResult:pluginResult callbackId:self.onVolumeButtonPressedHandlerId]; + }]; +} + +- (void)setSystemVolume:(CGFloat)volume { + [[MPMusicPlayerController applicationMusicPlayer] setVolume:(float)volume]; +} + -(void)runBlockWithTryCatch:(void (^)(void))block { @try { block(); From fe42fe8295862e2c3c6f46967d60192aeb422a9e Mon Sep 17 00:00:00 2001 From: parveshneedhoo Date: Mon, 28 Aug 2023 10:24:56 +0400 Subject: [PATCH 2/5] remove setvolume onpause --- src/ios/CDVVolumeButtons.m | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ios/CDVVolumeButtons.m b/src/ios/CDVVolumeButtons.m index 34c4aa3..d006a3a 100644 --- a/src/ios/CDVVolumeButtons.m +++ b/src/ios/CDVVolumeButtons.m @@ -22,7 +22,6 @@ @implementation CDVVolumeButtons - (void)onPause { [self runBlockWithTryCatch:^{ - [self setSystemVolume:self.userVolume]; self.appIsActive = NO; [self.session removeObserver:self forKeyPath:@"outputVolume"]; }]; From c20dc2509a348b224624802e7d2de2e8d7f99a0a Mon Sep 17 00:00:00 2001 From: parveshneedhoo Date: Mon, 4 Sep 2023 10:05:44 +0400 Subject: [PATCH 3/5] refactor code --- src/ios/CDVVolumeButtons.m | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/src/ios/CDVVolumeButtons.m b/src/ios/CDVVolumeButtons.m index d006a3a..98ab19e 100644 --- a/src/ios/CDVVolumeButtons.m +++ b/src/ios/CDVVolumeButtons.m @@ -6,12 +6,12 @@ @interface CDVVolumeButtons : CDVPlugin { // Member variables go here. } -@property (nonatomic, strong) MPVolumeView *volumeView; +@property (nonatomic, strong) MPVolumeView *volumeView; @property (nonatomic, strong) AVAudioSession *session; @property (nonatomic, strong) NSString *sessionCategory; -@property (nonatomic, assign) float userVolume; -@property (nonatomic, assign) bool isAdjustingInitialVolume; -@property (nonatomic, assign) bool appIsActive; +@property (nonatomic, assign) float userVolume; +@property (nonatomic, assign) bool isAdjustingInitialVolume; +@property (nonatomic, assign) bool appIsActive; @property (nonatomic, assign) AVAudioSessionCategoryOptions sessionOptions; @property (nonatomic) NSString *onVolumeButtonPressedHandlerId; @end @@ -22,8 +22,7 @@ @implementation CDVVolumeButtons - (void)onPause { [self runBlockWithTryCatch:^{ - self.appIsActive = NO; - [self.session removeObserver:self forKeyPath:@"outputVolume"]; + [self removeListenersAndObservers]; }]; } @@ -49,11 +48,21 @@ - (void)start:(CDVInvokedUrlCommand*)command { - (void)stop:(CDVInvokedUrlCommand*)command { [self runBlockWithTryCatch:^{ - [self.session removeObserver:self forKeyPath:@"outputVolume"]; - [[NSNotificationCenter defaultCenter] removeObserver:self]; + [self removeListenersAndObservers]; }]; } +- (void)removeListenersAndObservers { + if (!self.appIsActive) return; + self.appIsActive = NO; + @try { + [self.session removeObserver:self forKeyPath:@"outputVolume"]; + } + @catch (NSException * __unused exception) { + } + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} + - (void)setupAudioSession { self.sessionCategory = AVAudioSessionCategoryPlayback; self.sessionOptions = AVAudioSessionCategoryOptionMixWithOthers; @@ -114,7 +123,7 @@ - (void)audioSessionInterrupted:(NSNotification*)notification { - (void)applicationDidChangeActive:(NSNotification *)notification { self.appIsActive = [notification.name isEqualToString:UIApplicationDidBecomeActiveNotification]; - if (self.appIsActive ) { + if (self.appIsActive) { [self setVolume]; } } @@ -139,14 +148,14 @@ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(N [self setVolume]; return; } - [self takeImage]; + [self callback]; [self setVolume]; } else { [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; } } -- (void)takeImage { +- (void)callback { [self runBlockWithTryCatch:^{ CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; [pluginResult setKeepCallback:@YES]; From edd1df1bc2ca2148b2f8926da94e6f8398c84afd Mon Sep 17 00:00:00 2001 From: parveshneedhoo Date: Thu, 7 Sep 2023 10:19:42 +0400 Subject: [PATCH 4/5] one line statements --- src/ios/CDVVolumeButtons.m | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/ios/CDVVolumeButtons.m b/src/ios/CDVVolumeButtons.m index 98ab19e..8416c9f 100644 --- a/src/ios/CDVVolumeButtons.m +++ b/src/ios/CDVVolumeButtons.m @@ -54,6 +54,7 @@ - (void)stop:(CDVInvokedUrlCommand*)command { - (void)removeListenersAndObservers { if (!self.appIsActive) return; + self.appIsActive = NO; @try { [self.session removeObserver:self forKeyPath:@"outputVolume"]; @@ -139,10 +140,8 @@ - (void)setVolume { - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if (context == sessionContext) { - if (!self.appIsActive) { - // Probably control center, skip blocks - return; - } + if (!self.appIsActive) return; + if (self.isAdjustingInitialVolume) { self.isAdjustingInitialVolume = false; [self setVolume]; From a43f15d53f09bf501080a1e9261346eff8880cea Mon Sep 17 00:00:00 2001 From: dinitri ragoo Date: Thu, 7 Sep 2023 15:19:48 +0400 Subject: [PATCH 5/5] bump versoin 1.0.4 --- package-lock.json | 4 ++-- package.json | 2 +- plugin.xml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index e2e282b..d9fe193 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@spoonconsulting/cordova-plugin-volume-buttons", - "version": "1.0.3", + "version": "1.0.4", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@spoonconsulting/cordova-plugin-volume-buttons", - "version": "1.0.3", + "version": "1.0.4", "license": "ISC" } } diff --git a/package.json b/package.json index 91744fe..d431cee 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@spoonconsulting/cordova-plugin-volume-buttons", - "version": "1.0.3", + "version": "1.0.4", "description": "cordova-plugin-volume-buttons", "cordova": { "id": "@spoonconsulting/cordova-plugin-volume-buttons", diff --git a/plugin.xml b/plugin.xml index 4367ca1..cfeb9ba 100644 --- a/plugin.xml +++ b/plugin.xml @@ -1,5 +1,5 @@ - + cordova-plugin-volume-buttons