[vlc-commits] macosx: move integration with third party players to the new playlist

Felix Paul Kühne git at videolan.org
Mon Mar 11 01:09:05 CET 2019


vlc | branch: master | Felix Paul Kühne <felix at feepk.net> | Mon Mar 11 00:25:45 2019 +0100| [6739fc20792b877050b925a399b95d738e24ba50] | committer: Felix Paul Kühne

macosx: move integration with third party players to the new playlist

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=6739fc20792b877050b925a399b95d738e24ba50
---

 .../gui/macosx/coreinteraction/VLCInputManager.h   |   2 -
 .../gui/macosx/coreinteraction/VLCInputManager.m   | 113 ------------------
 modules/gui/macosx/main/VLCMain.m                  |   1 -
 modules/gui/macosx/playlist/VLCPlayerController.m  | 127 +++++++++++++++++++++
 4 files changed, 127 insertions(+), 116 deletions(-)

diff --git a/modules/gui/macosx/coreinteraction/VLCInputManager.h b/modules/gui/macosx/coreinteraction/VLCInputManager.h
index 7187d83b0f..47bb1ddaa2 100644
--- a/modules/gui/macosx/coreinteraction/VLCInputManager.h
+++ b/modules/gui/macosx/coreinteraction/VLCInputManager.h
@@ -36,8 +36,6 @@
 
 - (void)playbackStatusUpdated;
 
-- (void)onPlaybackHasEnded:(id)sender;
-
 - (BOOL)hasInput;
 
 @end
diff --git a/modules/gui/macosx/coreinteraction/VLCInputManager.m b/modules/gui/macosx/coreinteraction/VLCInputManager.m
index 9f85211605..b060ad0e3e 100644
--- a/modules/gui/macosx/coreinteraction/VLCInputManager.m
+++ b/modules/gui/macosx/coreinteraction/VLCInputManager.m
@@ -26,9 +26,6 @@
 #import "main/CompatibilityFixes.h"
 #import "main/VLCMain.h"
 #import "menus/VLCMainMenu.h"
-#import "os-integration/VLCRemoteControlService.h"
-#import "os-integration/iTunes.h"
-#import "os-integration/Spotify.h"
 #import "panels/VLCTrackSynchronizationWindowController.h"
 #import "panels/dialogs/VLCResumeDialogController.h"
 #import "windows/extensions/VLCExtensionsManager.h"
@@ -126,15 +123,6 @@ static int InputEvent(vlc_object_t *p_this, const char *psz_var,
 
     input_thread_t *p_current_input;
     dispatch_queue_t informInputChangedQueue;
-
-    /* iTunes/Spotify play/pause support */
-    BOOL b_has_itunes_paused;
-    BOOL b_has_spotify_paused;
-
-    /* remote control support */
-    VLCRemoteControlService *_remoteControlService;
-
-    NSTimer *hasEndedTimer;
 }
 @end
 
@@ -160,11 +148,6 @@ static int InputEvent(vlc_object_t *p_this, const char *psz_var,
         var_AddCallback(pl_Get(getIntf()), "input-current", InputThreadChanged, (__bridge void *)self);
 
         informInputChangedQueue = dispatch_queue_create("org.videolan.vlc.inputChangedQueue", DISPATCH_QUEUE_SERIAL);
-
-        if (@available(macOS 10.12.2, *)) {
-            _remoteControlService = [[VLCRemoteControlService alloc] init];
-            [_remoteControlService subscribeToRemoteCommands];
-        }
     }
     return self;
 }
@@ -179,9 +162,6 @@ static int InputEvent(vlc_object_t *p_this, const char *psz_var,
 - (void)deinit
 {
     msg_Dbg(getIntf(), "Deinitializing input manager");
-    if (@available(macOS 10.12.2, *)) {
-        [_remoteControlService unsubscribeFromRemoteCommands];
-    }
 
     if (p_current_input) {
         /* continue playback where you left off */
@@ -267,16 +247,7 @@ static int InputEvent(vlc_object_t *p_this, const char *psz_var,
         state = var_GetInteger(p_current_input, "state");
     }
 
-    // cancel itunes timer if next item starts playing
-    if (state > -1 && state != END_S) {
-        if (hasEndedTimer) {
-            [hasEndedTimer invalidate];
-            hasEndedTimer = nil;
-        }
-    }
-
     if (state == PLAYING_S) {
-        [self stopItunesPlayback];
         [[o_main mainWindow] setPause];
     } else {
         [[o_main mainMenu] setSubmenusEnabled: FALSE];
@@ -286,96 +257,12 @@ static int InputEvent(vlc_object_t *p_this, const char *psz_var,
             /* continue playback where you left off */
             if (p_current_input)
                 [self storePlaybackPositionForItem:p_current_input];
-
-            if (hasEndedTimer) {
-                [hasEndedTimer invalidate];
-            }
-            hasEndedTimer = [NSTimer scheduledTimerWithTimeInterval: 0.5
-                                                             target: self
-                                                           selector: @selector(onPlaybackHasEnded:)
-                                                           userInfo: nil
-                                                            repeats: NO];
         }
     }
 
     [self updateMainWindow];
 }
 
-// Called when playback has ended and likely no subsequent media will start playing
-- (void)onPlaybackHasEnded:(id)sender
-{
-    msg_Dbg(getIntf(), "Playback has been ended");
-
-    [self resumeItunesPlayback];
-    hasEndedTimer = nil;
-}
-
-- (void)stopItunesPlayback
-{
-    intf_thread_t *p_intf = getIntf();
-    int64_t controlItunes = var_InheritInteger(p_intf, "macosx-control-itunes");
-    if (controlItunes <= 0)
-        return;
-
-    // pause iTunes
-    if (!b_has_itunes_paused) {
-        iTunesApplication *iTunesApp = (iTunesApplication *) [SBApplication applicationWithBundleIdentifier:@"com.apple.iTunes"];
-        if (iTunesApp && [iTunesApp isRunning]) {
-            if ([iTunesApp playerState] == iTunesEPlSPlaying) {
-                msg_Dbg(p_intf, "pausing iTunes");
-                [iTunesApp pause];
-                b_has_itunes_paused = YES;
-            }
-        }
-    }
-
-    // pause Spotify
-    if (!b_has_spotify_paused) {
-        SpotifyApplication *spotifyApp = (SpotifyApplication *) [SBApplication applicationWithBundleIdentifier:@"com.spotify.client"];
-
-        if (spotifyApp) {
-            if ([spotifyApp respondsToSelector:@selector(isRunning)] && [spotifyApp respondsToSelector:@selector(playerState)]) {
-                if ([spotifyApp isRunning] && [spotifyApp playerState] == kSpotifyPlayerStatePlaying) {
-                    msg_Dbg(p_intf, "pausing Spotify");
-                    [spotifyApp pause];
-                    b_has_spotify_paused = YES;
-                }
-            }
-        }
-    }
-}
-
-- (void)resumeItunesPlayback
-{
-    intf_thread_t *p_intf = getIntf();
-    if (var_InheritInteger(p_intf, "macosx-control-itunes") > 1) {
-        if (b_has_itunes_paused) {
-            iTunesApplication *iTunesApp = (iTunesApplication *) [SBApplication applicationWithBundleIdentifier:@"com.apple.iTunes"];
-            if (iTunesApp && [iTunesApp isRunning]) {
-                if ([iTunesApp playerState] == iTunesEPlSPaused) {
-                    msg_Dbg(p_intf, "unpausing iTunes");
-                    [iTunesApp playpause];
-                }
-            }
-        }
-
-        if (b_has_spotify_paused) {
-            SpotifyApplication *spotifyApp = (SpotifyApplication *) [SBApplication applicationWithBundleIdentifier:@"com.spotify.client"];
-            if (spotifyApp) {
-                if ([spotifyApp respondsToSelector:@selector(isRunning)] && [spotifyApp respondsToSelector:@selector(playerState)]) {
-                    if ([spotifyApp isRunning] && [spotifyApp playerState] == kSpotifyPlayerStatePaused) {
-                        msg_Dbg(p_intf, "unpausing Spotify");
-                        [spotifyApp play];
-                    }
-                }
-            }
-        }
-    }
-
-    b_has_itunes_paused = NO;
-    b_has_spotify_paused = NO;
-}
-
 - (void)updateMainWindow
 {
     [[o_main mainWindow] updateWindow];
diff --git a/modules/gui/macosx/main/VLCMain.m b/modules/gui/macosx/main/VLCMain.m
index 161e7fa018..ccc34f2f65 100644
--- a/modules/gui/macosx/main/VLCMain.m
+++ b/modules/gui/macosx/main/VLCMain.m
@@ -334,7 +334,6 @@ static VLCMain *sharedInstance = nil;
         return;
     b_intf_terminating = true;
 
-    [_input_manager onPlaybackHasEnded:nil];
     [_input_manager deinit];
 
     if (notification == nil)
diff --git a/modules/gui/macosx/playlist/VLCPlayerController.m b/modules/gui/macosx/playlist/VLCPlayerController.m
index 9086c9c6e8..81e484d1a4 100644
--- a/modules/gui/macosx/playlist/VLCPlayerController.m
+++ b/modules/gui/macosx/playlist/VLCPlayerController.m
@@ -21,7 +21,11 @@
  *****************************************************************************/
 
 #import "VLCPlayerController.h"
+
 #import "main/VLCMain.h"
+#import "os-integration/VLCRemoteControlService.h"
+#import "os-integration/iTunes.h"
+#import "os-integration/Spotify.h"
 
 #import <MediaPlayer/MediaPlayer.h>
 
@@ -60,6 +64,15 @@ NSString *VLCPlayerMuteChanged = @"VLCPlayerMuteChanged";
     vlc_player_vout_listener_id *_playerVoutListenerID;
     vlc_player_title_list *_currentTitleList;
     NSNotificationCenter *_defaultNotificationCenter;
+
+    /* remote control support */
+    VLCRemoteControlService *_remoteControlService;
+
+    /* iTunes/Spotify play/pause support */
+    BOOL _iTunesPlaybackWasPaused;
+    BOOL _SpotifyPlaybackWasPaused;
+
+    NSTimer *_playbackHasTruelyEndedTimer;
 }
 
 - (void)currentMediaItemChanged:(input_item_t *)newMediaItem;
@@ -420,6 +433,10 @@ static const struct vlc_player_aout_cbs player_aout_callbacks = {
         _playerVoutListenerID = vlc_player_vout_AddListener(_p_player,
                                                             &player_vout_callbacks,
                                                             (__bridge void *)self);
+        if (@available(macOS 10.12.2, *)) {
+            _remoteControlService = [[VLCRemoteControlService alloc] init];
+            [_remoteControlService subscribeToRemoteCommands];
+        }
     }
 
     return self;
@@ -427,6 +444,10 @@ static const struct vlc_player_aout_cbs player_aout_callbacks = {
 
 - (void)deinitialize
 {
+    [self onPlaybackHasTruelyEnded:nil];
+    if (@available(macOS 10.12.2, *)) {
+        [_remoteControlService unsubscribeFromRemoteCommands];
+    }
     if (_currentTitleList) {
         vlc_player_title_list_Release(_currentTitleList);
     }
@@ -584,6 +605,15 @@ static const struct vlc_player_aout_cbs player_aout_callbacks = {
     /* instead of using vlc_player_GetState, we cache the state and provide it through a synthesized getter
      * as the direct call might not reflect the actual state due the asynchronous API nature */
     _playerState = state;
+
+    /* we seem to start (over), don't start other players */
+    if (_playerState != VLC_PLAYER_STATE_STOPPED) {
+        if (_playbackHasTruelyEndedTimer) {
+            [_playbackHasTruelyEndedTimer invalidate];
+            _playbackHasTruelyEndedTimer = nil;
+        }
+    }
+
     [_defaultNotificationCenter postNotificationName:VLCPlayerStateChanged
                                               object:self];
 
@@ -607,6 +637,103 @@ static const struct vlc_player_aout_cbs player_aout_callbacks = {
                 break;
         }
     }
+
+    /* notify third party apps through an informal protocol that our state changed */
+    [[NSDistributedNotificationCenter defaultCenter] postNotificationName:@"VLCPlayerStateDidChange"
+                                                                   object:nil
+                                                                 userInfo:nil
+                                                       deliverImmediately:YES];
+
+    /* schedule a timer to restart iTunes / Spotify because we are done here */
+    if (_playerState == VLC_PLAYER_STATE_STOPPED) {
+        if (_playbackHasTruelyEndedTimer) {
+            [_playbackHasTruelyEndedTimer invalidate];
+        }
+        _playbackHasTruelyEndedTimer = [NSTimer scheduledTimerWithTimeInterval:0.5
+                                                                        target:self
+                                                                      selector:@selector(onPlaybackHasTruelyEnded:)
+                                                                      userInfo:nil
+                                                                       repeats:NO];
+    }
+
+    /* pause external players */
+    if (_playerState == VLC_PLAYER_STATE_PLAYING || _playerState == VLC_PLAYER_STATE_STARTED) {
+        [self stopOtherAudioPlaybackApps];
+    }
+}
+
+// Called when playback has truely ended and likely no subsequent media will start playing
+- (void)onPlaybackHasTruelyEnded:(id)sender
+{
+    msg_Dbg(getIntf(), "Playback has been ended");
+
+    [self resumeOtherAudioPlaybackApps];
+    _playbackHasTruelyEndedTimer = nil;
+}
+
+- (void)stopOtherAudioPlaybackApps
+{
+    intf_thread_t *p_intf = getIntf();
+    int64_t controlOtherPlayers = var_InheritInteger(p_intf, "macosx-control-itunes");
+    if (controlOtherPlayers <= 0)
+        return;
+
+    // pause iTunes
+    if (!_iTunesPlaybackWasPaused) {
+        iTunesApplication *iTunesApp = (iTunesApplication *) [SBApplication applicationWithBundleIdentifier:@"com.apple.iTunes"];
+        if (iTunesApp && [iTunesApp isRunning]) {
+            if ([iTunesApp playerState] == iTunesEPlSPlaying) {
+                msg_Dbg(p_intf, "pausing iTunes");
+                [iTunesApp pause];
+                _iTunesPlaybackWasPaused = YES;
+            }
+        }
+    }
+
+    // pause Spotify
+    if (!_SpotifyPlaybackWasPaused) {
+        SpotifyApplication *spotifyApp = (SpotifyApplication *) [SBApplication applicationWithBundleIdentifier:@"com.spotify.client"];
+        if (spotifyApp) {
+            if ([spotifyApp respondsToSelector:@selector(isRunning)] && [spotifyApp respondsToSelector:@selector(playerState)]) {
+                if ([spotifyApp isRunning] && [spotifyApp playerState] == kSpotifyPlayerStatePlaying) {
+                    msg_Dbg(p_intf, "pausing Spotify");
+                    [spotifyApp pause];
+                    _SpotifyPlaybackWasPaused = YES;
+                }
+            }
+        }
+    }
+}
+
+- (void)resumeOtherAudioPlaybackApps
+{
+    intf_thread_t *p_intf = getIntf();
+    if (var_InheritInteger(p_intf, "macosx-control-itunes") > 1) {
+        if (_iTunesPlaybackWasPaused) {
+            iTunesApplication *iTunesApp = (iTunesApplication *) [SBApplication applicationWithBundleIdentifier:@"com.apple.iTunes"];
+            if (iTunesApp && [iTunesApp isRunning]) {
+                if ([iTunesApp playerState] == iTunesEPlSPaused) {
+                    msg_Dbg(p_intf, "unpausing iTunes");
+                    [iTunesApp playpause];
+                }
+            }
+        }
+
+        if (_SpotifyPlaybackWasPaused) {
+            SpotifyApplication *spotifyApp = (SpotifyApplication *) [SBApplication applicationWithBundleIdentifier:@"com.spotify.client"];
+            if (spotifyApp) {
+                if ([spotifyApp respondsToSelector:@selector(isRunning)] && [spotifyApp respondsToSelector:@selector(playerState)]) {
+                    if ([spotifyApp isRunning] && [spotifyApp playerState] == kSpotifyPlayerStatePaused) {
+                        msg_Dbg(p_intf, "unpausing Spotify");
+                        [spotifyApp play];
+                    }
+                }
+            }
+        }
+    }
+
+    _iTunesPlaybackWasPaused = NO;
+    _SpotifyPlaybackWasPaused = NO;
 }
 
 - (void)errorChanged:(enum vlc_player_error)error



More information about the vlc-commits mailing list