Skip to content

Commit

Permalink
Try to make muting/unmuting more reliable
Browse files Browse the repository at this point in the history
Hopefully fixes #50 #51 #54 #55
  • Loading branch information
artemgordinskiy committed Apr 26, 2015
1 parent cc87aa5 commit 627b2c3
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 54 deletions.
2 changes: 1 addition & 1 deletion Spotifree.xcodeproj/project.pbxproj
Expand Up @@ -226,7 +226,7 @@
943164CD186C3724005277EA /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0620;
LastUpgradeCheck = 0630;
ORGANIZATIONNAME = Eneas;
};
buildConfigurationList = 943164D0186C3724005277EA /* Build configuration list for PBXProject "Spotifree" */;
Expand Down
3 changes: 2 additions & 1 deletion Spotifree/MenuController.m
Expand Up @@ -117,8 +117,9 @@ - (void)fixWrongLocationOfScriptingDefinitionFileIfNeeded {
#pragma mark -
#pragma SpotifyControllerDelegate
- (void)activeStateShouldGetUpdated:(SFSpotifyState)state {
if (!self.statusItem)
if (!self.statusItem) {
return;
}

NSString *label;
NSImage *icon;
Expand Down
109 changes: 57 additions & 52 deletions Spotifree/SpotifyController.m
Expand Up @@ -14,7 +14,7 @@
#define SPOTIFY_BUNDLE_IDENTIFIER @"com.spotify.client"

#define IDLE_TIME 0.5
#define TIMER_CHECK_AD [NSTimer scheduledTimerWithTimeInterval:IDLE_TIME target:self selector:@selector(checkForAd) userInfo:nil repeats:YES]
#define TIMER [NSTimer scheduledTimerWithTimeInterval:IDLE_TIME target:self selector:@selector(checkCurrentTrack) userInfo:nil repeats:YES]

@interface SpotifyController () {
NSInteger _currentVolume;
Expand All @@ -25,7 +25,8 @@ @interface SpotifyController () {
@property (strong) NSTimer *timer;

@property (assign) BOOL shouldRun;
@property (assign) BOOL muted;
@property (assign) BOOL isMuted;
@property (assign) BOOL isInTheProcessOfMuting;

@end

Expand All @@ -46,9 +47,9 @@ - (id)init
self.appData = [AppData sharedData];

self.shouldRun = YES;
self.isMuted = NO;
[self addObserver:self forKeyPath:@"shouldRun" options:NSKeyValueObservingOptionOld context:nil];

self.muted = NO;

[[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackStateChanged) name:@"com.spotify.client.PlaybackStateChanged" object:nil];
}
Expand All @@ -58,30 +59,25 @@ - (id)init

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if ([keyPath isEqualToString:@"shouldRun"]) {
[self.timer invalidate];

if (self.shouldRun) {
if (self.timer)
[self.timer invalidate];
self.timer = TIMER_CHECK_AD;
} else {
if (self.timer) {
[self.timer invalidate];
}
self.timer = TIMER;
}

if ([self.delegate respondsToSelector:@selector(activeStateShouldGetUpdated:)]) {
[self.delegate activeStateShouldGetUpdated:(self.shouldRun ? kSFSpotifyStateActive : kSFSpotifyStateInactive)];
}
}
}

- (void)playbackStateChanged {
if (self.shouldRun && ![self isPlaying]) {
self.shouldRun = NO;
} else if ((!self.shouldRun) && [self isPlaying]) {
self.shouldRun = YES;
if (self.isInTheProcessOfMuting) {
return;
}

[self checkForMusic];
self.shouldRun = [self isPlaying];
[self checkCurrentTrack];
}

#pragma mark -
Expand All @@ -90,70 +86,70 @@ - (void)startService {
[self playbackStateChanged];

if (self.shouldRun) {
self.timer = TIMER_CHECK_AD;
self.timer = TIMER;
} else {
[self.timer invalidate];
}
}

#pragma mark -
#pragma mark Timer Methods
- (void)checkForAd {
if ([self isAnAd]) {
[self.timer invalidate];
[self mute];

if ([self.delegate respondsToSelector:@selector(activeStateShouldGetUpdated:)]) {
[self.delegate activeStateShouldGetUpdated:kSFSpotifyStateBlockingAd];
}
}
}

- (void)checkForMusic {
if (!self.muted || [self isAnAd]) {
- (void)checkCurrentTrack {
// prevent relaunching Spotify on quit and muting it when it's not playing anything
if (![self isPlaying]) {
self.shouldRun = NO;
return;
}

[self unmute];

if (self.shouldRun) {
self.timer = TIMER_CHECK_AD;
}

if ([self.delegate respondsToSelector:@selector(activeStateShouldGetUpdated:)]) {
[self.delegate activeStateShouldGetUpdated:(self.shouldRun ? kSFSpotifyStateActive : kSFSpotifyStateInactive)];
if ([self isAnAd]) {
if (!self.isMuted) {
[self mute];
}

if ([self.delegate respondsToSelector:@selector(activeStateShouldGetUpdated:)]) {
[self.delegate activeStateShouldGetUpdated:kSFSpotifyStateBlockingAd];
}
} else {
if (self.isMuted) {
[self unmute];
}

if ([self.delegate respondsToSelector:@selector(activeStateShouldGetUpdated:)]) {
[self.delegate activeStateShouldGetUpdated:(self.shouldRun ? kSFSpotifyStateActive : kSFSpotifyStateInactive)];
}
}
}

#pragma mark -
#pragma mark Player Control Methods

- (void)mute {
self.muted = YES;

self.isInTheProcessOfMuting = YES;
_currentVolume = self.spotify.soundVolume;
[self.spotify pause];
[self.spotify setSoundVolume:0];
[self.spotify setSoundVolume: 0];
[self.spotify play];

if (self.appData.shouldShowNotifications) {
NSUserNotification *notification = [[NSUserNotification alloc] init];
[notification setTitle:@"Spotifree"];
[notification setInformativeText:[NSString stringWithFormat:@"A Spotify ad was detected! Music will be back in about %ld seconds…", (long)self.spotify.currentTrack.duration]];
[notification setSoundName:nil];

[[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification];
[self displayNotification: [NSString stringWithFormat:@"A Spotify ad was detected! Music will be back in about %ld seconds…", (long)self.spotify.currentTrack.duration]];
}

self.isMuted = YES;
self.isInTheProcessOfMuting = NO;
}

- (void)unmute {
self.muted = NO;

[self.spotify setSoundVolume:_currentVolume];
self.isMuted = NO;
}

- (BOOL)isAnAd {
BOOL isAnAd;

NSInteger currentTrackNumber = self.spotify.currentTrack.trackNumber;
NSString * currentTrackUrl = self.spotify.currentTrack.spotifyUrl;

@try {
isAnAd = [self.spotify.currentTrack.spotifyUrl hasPrefix:@"spotify:ad"];
isAnAd = ([currentTrackUrl hasPrefix:@"spotify:ad"] || currentTrackNumber == 0);
}
@catch (NSException *exception) {
isAnAd = NO;
Expand All @@ -167,7 +163,7 @@ - (BOOL)isPlaying {
BOOL isPlaying;

@try {
isPlaying = [self isRunning] && self.spotify.playerState == SpotifyEPlSPlaying;
isPlaying = ([self isRunning] && self.spotify.playerState == SpotifyEPlSPlaying);
}
@catch (NSException *exception) {
isPlaying = NO;
Expand All @@ -191,6 +187,15 @@ - (BOOL)isRunning {
return isRunning;
}

- (void)displayNotification:(NSString*)content {
NSUserNotification *notification = [[NSUserNotification alloc] init];
[notification setTitle:@"Spotifree"];
[notification setInformativeText:content];
[notification setSoundName:nil];

[[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification];
}

- (void)dealloc {
[[NSDistributedNotificationCenter defaultCenter] removeObserver:self];
[self removeObserver:self forKeyPath:@"shouldRun"];
Expand Down

0 comments on commit 627b2c3

Please sign in to comment.