[vlc-commits] macosx: add player controller

Felix Paul Kühne git at videolan.org
Sun Feb 3 14:51:03 CET 2019


vlc | branch: master | Felix Paul Kühne <felix at feepk.net> | Sun Feb  3 00:23:22 2019 +0100| [c1bf0505b484646d67820dd60c50591a98174c5e] | committer: Felix Paul Kühne

macosx: add player controller

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

 .../package/macosx/VLC.xcodeproj/project.pbxproj   |  22 +-
 modules/gui/macosx/Makefile.am                     |   2 +
 modules/gui/macosx/playlist/VLCPlayerController.h  | 359 ++++++++++++
 modules/gui/macosx/playlist/VLCPlayerController.m  | 601 +++++++++++++++++++++
 .../gui/macosx/playlist/VLCPlaylistController.m    |   1 -
 5 files changed, 982 insertions(+), 3 deletions(-)

diff --git a/extras/package/macosx/VLC.xcodeproj/project.pbxproj b/extras/package/macosx/VLC.xcodeproj/project.pbxproj
index 773e4d34e1..b14551d29c 100644
--- a/extras/package/macosx/VLC.xcodeproj/project.pbxproj
+++ b/extras/package/macosx/VLC.xcodeproj/project.pbxproj
@@ -149,6 +149,8 @@
 		7DB7F20B20CC082800C2CAED /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7DB7F20A20CC082800C2CAED /* QuartzCore.framework */; };
 		7DC21A7422049A6600F98A02 /* VLCOpenInputMetadata.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DC21A7322049A6600F98A02 /* VLCOpenInputMetadata.m */; };
 		7DD2F5C52081B73B007EE187 /* VLCRemoteControlService.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DD2F5C42081B73B007EE187 /* VLCRemoteControlService.m */; };
+		7DE9C7D82205EF030089108F /* VLCPlayerController.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DE9C7D72205EF030089108F /* VLCPlayerController.m */; };
+		7DE9C7DD220728420089108F /* VLCPlayerController.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DE9C7DC220728420089108F /* VLCPlayerController.m */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXFileReference section */
@@ -509,6 +511,9 @@
 		7DC21A7322049A6600F98A02 /* VLCOpenInputMetadata.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VLCOpenInputMetadata.m; sourceTree = "<group>"; };
 		7DD2F5C32081B73B007EE187 /* VLCRemoteControlService.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VLCRemoteControlService.h; sourceTree = "<group>"; };
 		7DD2F5C42081B73B007EE187 /* VLCRemoteControlService.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VLCRemoteControlService.m; sourceTree = "<group>"; };
+		7DE9C7D72205EF030089108F /* VLCPlayerController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VLCPlayerController.m; sourceTree = "<group>"; };
+		7DE9C7DB220728420089108F /* VLCPlayerController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VLCPlayerController.h; sourceTree = "<group>"; };
+		7DE9C7DC220728420089108F /* VLCPlayerController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VLCPlayerController.m; sourceTree = "<group>"; };
 		7DF0435E1972E26A0022B534 /* VLCAddonListItem.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VLCAddonListItem.h; sourceTree = "<group>"; };
 		7DF0435F1972E26A0022B534 /* VLCAddonListItem.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VLCAddonListItem.m; sourceTree = "<group>"; };
 		7DF812ED1B555A340052293C /* VLCInputManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VLCInputManager.h; sourceTree = "<group>"; };
@@ -619,6 +624,7 @@
 				089C1671FE841209C02AAC07 /* Frameworks and Libraries */,
 				19C28FB8FE9D52D311CA2CBB /* Products */,
 				7DB7F1EA20CC036C00C2CAED /* Frameworks */,
+				7DE9C7DA2207281F0089108F /* Recovered References */,
 			);
 			name = vlc;
 			sourceTree = "<group>";
@@ -937,6 +943,8 @@
 		1C1ED5142205A96600811EC0 /* playlist */ = {
 			isa = PBXGroup;
 			children = (
+				7DE9C7DB220728420089108F /* VLCPlayerController.h */,
+				7DE9C7DC220728420089108F /* VLCPlayerController.m */,
 				7D445D7F2202524000263D34 /* VLCPlaylistController.h */,
 				7D445D802202524000263D34 /* VLCPlaylistController.m */,
 				7D0F640A2202163E00FDB91F /* VLCPlaylistDataSource.h */,
@@ -1287,6 +1295,14 @@
 			name = Frameworks;
 			sourceTree = "<group>";
 		};
+		7DE9C7DA2207281F0089108F /* Recovered References */ = {
+			isa = PBXGroup;
+			children = (
+				7DE9C7D72205EF030089108F /* VLCPlayerController.m */,
+			);
+			name = "Recovered References";
+			sourceTree = "<group>";
+		};
 		8E445F86047289E50059A3A7 /* File Icons */ = {
 			isa = PBXGroup;
 			children = (
@@ -1476,7 +1492,7 @@
 					};
 				};
 			};
-			buildConfigurationList = C2F2A6EA09588F1B00018C74 /* Build configuration list for PBXProject "vlc" */;
+			buildConfigurationList = C2F2A6EA09588F1B00018C74 /* Build configuration list for PBXProject "VLC" */;
 			compatibilityVersion = "Xcode 6.3";
 			developmentRegion = English;
 			hasScannedForEncodings = 1;
@@ -1519,6 +1535,7 @@
 				1CCC88F82078A3D500E5626F /* CoreDialogs.xib in Sources */,
 				1CCC88F92078A3D500E5626F /* DetachedVideoWindow.xib in Sources */,
 				1CCC88FA2078A3D500E5626F /* ErrorPanel.xib in Sources */,
+				7DE9C7D82205EF030089108F /* VLCPlayerController.m in Sources */,
 				1CCC88FB2078A3D500E5626F /* Help.xib in Sources */,
 				1CCC88FC2078A3D500E5626F /* LogMessageWindow.xib in Sources */,
 				1CCC88FD2078A3D500E5626F /* Open.xib in Sources */,
@@ -1553,6 +1570,7 @@
 				1C31138E1E508C6900D4DD76 /* VLCAboutWindowController.m in Sources */,
 				1C3113901E508C6900D4DD76 /* VLCHelpWindowController.m in Sources */,
 				1C3113921E508C6900D4DD76 /* VLCAddonListItem.m in Sources */,
+				7DE9C7DD220728420089108F /* VLCPlayerController.m in Sources */,
 				1C3113941E508C6900D4DD76 /* VLCAddonsWindowController.m in Sources */,
 				7D2E0EDE20CD206F0033A221 /* VLCVideoWindowCommon.m in Sources */,
 				1C3113961E508C6900D4DD76 /* applescript.m in Sources */,
@@ -1917,7 +1935,7 @@
 			defaultConfigurationIsVisible = 0;
 			defaultConfigurationName = Default;
 		};
-		C2F2A6EA09588F1B00018C74 /* Build configuration list for PBXProject "vlc" */ = {
+		C2F2A6EA09588F1B00018C74 /* Build configuration list for PBXProject "VLC" */ = {
 			isa = XCConfigurationList;
 			buildConfigurations = (
 				C2F2A6EB09588F1B00018C74 /* Development */,
diff --git a/modules/gui/macosx/Makefile.am b/modules/gui/macosx/Makefile.am
index 04a416008e..06eeac58fd 100644
--- a/modules/gui/macosx/Makefile.am
+++ b/modules/gui/macosx/Makefile.am
@@ -119,6 +119,8 @@ libmacosx_plugin_la_SOURCES = \
 	gui/macosx/panels/dialogs/VLCResumeDialogController.m \
 	gui/macosx/panels/dialogs/VLCTextfieldPanelController.h \
 	gui/macosx/panels/dialogs/VLCTextfieldPanelController.m \
+	gui/macosx/playlist/VLCPlayerController.h \
+	gui/macosx/playlist/VLCPlayerController.m \
 	gui/macosx/playlist/VLCPlaylistController.h \
 	gui/macosx/playlist/VLCPlaylistController.m \
 	gui/macosx/playlist/VLCPlaylistDataSource.h \
diff --git a/modules/gui/macosx/playlist/VLCPlayerController.h b/modules/gui/macosx/playlist/VLCPlayerController.h
new file mode 100644
index 0000000000..2e55196875
--- /dev/null
+++ b/modules/gui/macosx/playlist/VLCPlayerController.h
@@ -0,0 +1,359 @@
+/*****************************************************************************
+ * VLCPlayerController.h: MacOS X interface module
+ *****************************************************************************
+ * Copyright (C) 2019 VLC authors and VideoLAN
+ *
+ * Authors: Felix Paul Kühne <fkuehne # videolan -dot- org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#import <Foundation/Foundation.h>
+#import <vlc_player.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+extern NSString *VLCPlayerCurrentMediaItem;
+/**
+ * Listen to VLCPlayerCurrentMediaItemChanged to notified if the current media item changes for the player
+ * @note the affected player object will be the object of the notification
+ * @note the userInfo dictionary will have the pointer to the new input_item_t for key VLCPlayerCurrentMediaItem
+ */
+extern NSString *VLCPlayerCurrentMediaItemChanged;
+
+/**
+ * Listen to VLCPlayerStateChanged to be notified if the player's state changes
+ * @note the affected player object will be the object of the notification
+ */
+extern NSString *VLCPlayerStateChanged;
+
+/**
+ * Listen to VLCPlayerErrorChanged to be notified if the player's error expression changes
+ * @note the affected player object will be the object of the notification
+ */
+extern NSString *VLCPlayerErrorChanged;
+
+extern NSString *VLCPlayerBufferFill;
+/**
+ * Listen to VLCPlayerBufferChanged to be notified if the player's buffer value changes
+ * @note the affected player object will be the object of the notification
+ * @note the userInfo dictionary will have the float value indicating the fill state as percentage from 0.0 to 1.0
+ * for key VLCPlayerBufferFill */
+extern NSString *VLCPlayerBufferChanged;
+
+/**
+ * Listen to VLCPlayerRateChanged to be notified if the player's playback rate changes
+ * @note the affected player object will be the object of the notification
+ */
+extern NSString *VLCPlayerRateChanged;
+
+/**
+ * Listen to VLCPlayerCapabilitiesChanged to be notified if the player's capabilities change
+ * Those are: seekable, rewindable, pausable, recordable, rateChangable
+ * @note the affected player object will be the object of the notification
+ */
+extern NSString *VLCPlayerCapabilitiesChanged;
+
+/**
+ * Listen to VLCPlayerTimeAndPositionChanged to be notified if playback position and/or time change
+ * @note the affected player object will be the object of the notification
+ */
+extern NSString *VLCPlayerTimeAndPositionChanged;
+
+/**
+ * Listen to VLCPlayerLengthChanged to be notified if the length of the current media changes
+ * @note the affected player object will be the object of the notification
+ */
+extern NSString *VLCPlayerLengthChanged;
+
+/**
+ * Listen to VLCPlayerAudioDelayChanged to be notified if the audio delay of the current media changes
+ * @note the affected player object will be the object of the notification
+ */
+extern NSString *VLCPlayerAudioDelayChanged;
+
+/**
+ * Listen to VLCPlayerSubtitlesDelayChanged to be notified if the subtitles delay of the current media changes
+ * @note the affected player object will be the object of the notification
+ */
+extern NSString *VLCPlayerSubtitlesDelayChanged;
+
+/**
+ * Listen to VLCPlayerRecordingChanged to be notified if the recording state of the current media changes
+ * @note the affected player object will be the object of the notification
+ */
+extern NSString *VLCPlayerRecordingChanged;
+
+/**
+ * Listen to VLCPlayerFullscreenChanged to be notified whether the fullscreen state of the video output changes
+ * @note the affected player object will be the object of the notification
+ */
+extern NSString *VLCPlayerFullscreenChanged;
+
+/**
+ * Listen to VLCPlayerWallpaperModeChanged to be notified whether the fullscreen state of the video output changes
+ * @note the affected player object will be the object of the notification
+ */
+extern NSString *VLCPlayerWallpaperModeChanged;
+
+/**
+ * Listen to VLCPlayerVolumeChanged to be notified whether the audio output volume changes
+ * @note the affected player object will be the object of the notification
+ */
+extern NSString *VLCPlayerVolumeChanged;
+
+/**
+ * Listen to VLCPlayerMuteChanged to be notified whether the audio output is muted or not
+ * @note the affected player object will be the object of the notification
+ */
+extern NSString *VLCPlayerMuteChanged;
+
+ at interface VLCPlayerController : NSObject
+
+- (instancetype)initWithPlayer:(vlc_player_t *)player;
+
+/**
+ * Start playback of the current media
+ * @return VLC_SUCCESS on success, otherwise a VLC error
+ */
+- (int)start;
+
+/**
+ * Request to start playback in paused state
+ * @param yes if you want to start in paused state, no if you want to cancel your previous request
+ */
+- (void)startInPausedState:(BOOL)startPaused;
+
+/**
+ * Pause the current playback
+ */
+- (void)pause;
+
+/**
+ * Resume the current playback
+ */
+- (void)resume;
+
+/**
+ * Stop the current playback
+ */
+- (void)stop;
+
+/**
+ * Define the action to perform after playback of the current media stopped (for any reason)
+ * Options are: continue with next time, pause on last frame, stop even if there is a next item and quit VLC
+ * @see the vlc_player_media_stopped_action enum for details
+ */
+ at property (readwrite, nonatomic) enum vlc_player_media_stopped_action actionAfterStop;
+
+/**
+ * Move on to the next video frame and pause
+ * @warning this relies on a gross hack in the core and will work for 20 consecutive frames maximum only
+ */
+- (void)nextVideoFrame;
+
+/**
+ * get the current media item
+ * @return the current media item, NULL if none
+ */
+ at property (readonly, nullable) input_item_t * currentMedia;
+/**
+ * set the current media item
+ * @note this is typically done by the associated playlist so you should not need to do it
+ * @return VLC_SUCCESS on success, another VLC error on failure
+ */
+- (int)setCurrentMedia:(input_item_t *)currentMedia;
+
+/**
+ * the current player state
+ * @return a value according to the vlc_player_state enum
+ * @note listen to VLCPlayerStateChanged to be notified about changes to this property
+ */
+ at property (readonly) enum vlc_player_state playerState;
+
+/**
+ * the current error value
+ * @return a value according to the vlc_player_error enum
+ * @note listen to VLCPlayerErrorChanged to be notified about changes to this property
+ */
+ at property (readonly) enum vlc_player_error error;
+
+/**
+ * the current buffer state
+ * @return a float ranging from 0.0 to 1.0 indicating the buffer fill state as percentage
+ * @note listen to VLCPlayerBufferChanged to be notified about changes to this property
+ */
+ at property (readonly) float bufferFill;
+
+/**
+ * the current playback rate
+ * @return a float larger than 0.0 indicating the playback rate in multiples
+ * @note 1.0 defines playback at the default rate, <1.0 will slow things, >1.0 will be faster
+ */
+ at property (readwrite, nonatomic) float playbackRate;
+
+/**
+ * helper function to increment the playback rate
+ */
+- (void)incrementPlaybackRate;
+/**
+ * helper function to decrement the playback rate
+ */
+- (void)decrementPlaybackRate;
+
+/**
+ * is the currently playing input seekable?
+ * @return a BOOL value indicating whether the current input is seekable
+ * @note listen to VLCPlayerCapabilitiesChanged to be notified about changes to this property
+ */
+ at property (readonly) BOOL seekable;
+
+/**
+ * is the currently playing input rewindable?
+ * @return a BOOL value indicating whether the current input is rewindable
+ * @note listen to VLCPlayerCapabilitiesChanged to be notified about changes to this property
+ */
+ at property (readonly) BOOL rewindable;
+
+/**
+ * is the currently playing input pausable?
+ * @return a BOOL value indicating whether the current input can be paused
+ * @note listen to VLCPlayerCapabilitiesChanged to be notified about changes to this property
+ */
+ at property (readonly) BOOL pausable;
+
+/**
+ * is the currently playing input recordable?
+ * @return a BOOL value indicating whether the current input can be recorded
+ * @note listen to VLCPlayerCapabilitiesChanged to be notified about changes to this property
+ */
+ at property (readonly) BOOL recordable;
+
+/**
+ * is the currently playing input rateChangable?
+ * @return a BOOL value indicating whether the playback rate can be changed for the current input
+ * @note listen to VLCPlayerCapabilitiesChanged to be notified about changes to this property
+ */
+ at property (readonly) BOOL rateChangable;
+
+/**
+ * the time of the currently playing media
+ * @return a valid time or VLC_TICK_INVALID (if no media is set, the media
+ * doesn't have any time, if playback is not yet started or in case of error)
+ * @note A started and playing media doesn't have necessarily a valid time.
+ * @note listen to VLCPlayerTimeAndPositionChanged to be notified about changes to this property
+ */
+ at property (readonly) vlc_tick_t time;
+
+/**
+ * set the playback position in time for the currently playing media
+ * @note this methods prefers speed in seeking over precision
+ * @note This method can be called before starting to set a starting position.
+ */
+- (void)setTimeFast:(vlc_tick_t)time;
+
+/**
+ * set the playback position in time for the currently playing media
+ * @note this methods prefers precision in seeking over speed
+ * @note This method can be called before starting to set a starting position.
+ */
+- (void)setTimePrecise:(vlc_tick_t)time;
+
+/**
+ * the time of the currently playing media
+ * @return a valid time or VLC_TICK_INVALID (if no media is set, the media
+ * doesn't have any time, if playback is not yet started or in case of error)
+ * @note A started and playing media doesn't have necessarily a valid time.
+ * @note listen to VLCPlayerTimeAndPositionChanged to be notified about changes to this property
+ */
+ at property (readonly) float position;
+
+/**
+ * set the playback position as a percentage (range 0.0 to 1.0) for the currently playing media
+ * @note this methods prefers speed in seeking over precision
+ * @note This method can be called before starting to set a starting position.
+ */
+- (void)setPositionFast:(float)position;
+
+/**
+ * set the playback position as a percentage (range 0.0 to 1.0) for the currently playing media
+ * @note this methods prefers precision in seeking over speed
+ * @note This method can be called before starting to set a starting position.
+ */
+- (void)setPositionPrecise:(float)position;
+
+/**
+ * the length of the currently playing media in ticks
+ * @return a valid time or VLC_TICK_INVALID (if no media is set, the media
+ * doesn't have any length, if playback is not yet started or in case of error)
+ * @note A started and playing media doesn't have necessarily a valid length.
+ * @note listen to VLCPlayerLengthChanged to be notified about changes to this property
+ */
+ at property (readonly) vlc_tick_t length;
+
+/**
+ * the audio delay for the current media
+ * @warning this property expects you to provide an absolute delay time
+ * @return the audio delay in vlc ticks
+ * @note listed to VLCPlayerAudioDelayChanged to be notified about changes to this property
+ */
+ at property (readwrite, nonatomic) vlc_tick_t audioDelay;
+
+/**
+ * the subtitles delay for the current media
+ * @warning this property expects you to provide an absolute delay time
+ * @return the subtitles delay in vlc ticks
+ * @note listen to VLCPlayerSubtitlesDelayChanged to be notified about changes to this property
+ */
+ at property (readwrite, nonatomic) vlc_tick_t subtitlesDelay;
+
+/**
+ * enable recording of the current media or check if it is being done
+ * @note listen to VLCPlayerRecordingChanged to be notified about changes to this property
+ */
+ at property (readwrite, nonatomic) BOOL enableRecording;
+
+#pragma mark - video output properties
+
+/**
+ * indicates whether video is displayed in fullscreen or shall to
+ * @note listen to VLCPlayerFullscreenChanged to be notified about changes to this property
+ */
+ at property (readwrite, nonatomic) BOOL fullscreen;
+
+/**
+ * indicates whether video is displaed in wallpaper mode or shall to
+ * @note listen to VLCPlayerWallpaperModeChanged to be notified about changes to this property
+ */
+ at property (readwrite, nonatomic) BOOL wallpaperMode;
+
+#pragma mark - audio output properties
+
+/**
+ * reveals or sets the audio output volume
+ * range is 0.0 to 2.0 in percentage, whereas 100% is the unamplified maximum
+ * @note listen to VLCPlayerVolumeChanged to be notified about changes to this property
+ */
+ at property (readwrite, nonatomic) float volume;
+
+/**
+ * reveals or sets whether audio output is set to mute or not
+ * @note listen to VLCPlayerMuteChanged to be notified about changes to this property
+ */
+ at property (readwrite, nonatomic) BOOL mute;
+
+ at end
+
+NS_ASSUME_NONNULL_END
diff --git a/modules/gui/macosx/playlist/VLCPlayerController.m b/modules/gui/macosx/playlist/VLCPlayerController.m
new file mode 100644
index 0000000000..d3f7ad5fef
--- /dev/null
+++ b/modules/gui/macosx/playlist/VLCPlayerController.m
@@ -0,0 +1,601 @@
+/*****************************************************************************
+ * VLCPlayerController.m: MacOS X interface module
+ *****************************************************************************
+ * Copyright (C) 2019 VLC authors and VideoLAN
+ *
+ * Authors: Felix Paul Kühne <fkuehne # videolan -dot- org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#import "VLCPlayerController.h"
+
+NSString *VLCPlayerCurrentMediaItem = @"VLCPlayerCurrentMediaItem";
+NSString *VLCPlayerCurrentMediaItemChanged = @"VLCPlayerCurrentMediaItemChanged";
+NSString *VLCPlayerStateChanged = @"VLCPlayerStateChanged";
+NSString *VLCPlayerErrorChanged = @"VLCPlayerErrorChanged";
+NSString *VLCPlayerBufferFill = @"VLCPlayerBufferFill";
+NSString *VLCPlayerBufferChanged = @"VLCPlayerBufferChanged";
+NSString *VLCPlayerRateChanged = @"VLCPlayerRateChanged";
+NSString *VLCPlayerCapabilitiesChanged = @"VLCPlayerCapabilitiesChanged";
+NSString *VLCPlayerTimeAndPositionChanged = @"VLCPlayerTimeAndPositionChanged";
+NSString *VLCPlayerLengthChanged = @"VLCPlayerLengthChanged";
+NSString *VLCPlayerAudioDelayChanged = @"VLCPlayerAudioDelayChanged";
+NSString *VLCPlayerSubtitlesDelayChanged = @"VLCPlayerSubtitlesDelayChanged";
+NSString *VLCPlayerRecordingChanged = @"VLCPlayerRecordingChanged";
+NSString *VLCPlayerFullscreenChanged = @"VLCPlayerFullscreenChanged";
+NSString *VLCPlayerWallpaperModeChanged = @"VLCPlayerWallpaperModeChanged";
+NSString *VLCPlayerVolumeChanged = @"VLCPlayerVolumeChanged";
+NSString *VLCPlayerMuteChanged = @"VLCPlayerMuteChanged";
+
+ at interface VLCPlayerController ()
+{
+    vlc_player_t *_p_player;
+    vlc_player_listener_id *_playerListenerID;
+    vlc_player_aout_listener_id *_playerAoutListenerID;
+    vlc_player_vout_listener_id *_playerVoutListenerID;
+    NSNotificationCenter *_defaultNotificationCenter;
+}
+
+- (void)currentMediaItemChanged:(input_item_t *)newMediaItem;
+- (void)stateChanged:(enum vlc_player_state)state;
+- (void)errorChanged:(enum vlc_player_error)error;
+- (void)newBufferingValue:(float)bufferValue;
+- (void)newRateValue:(float)rateValue;
+- (void)capabilitiesChanged:(int)newCapabilities;
+- (void)position:(float)position andTimeChanged:(vlc_tick_t)time;
+- (void)lengthChanged:(vlc_tick_t)length;
+- (void)audioDelayChanged:(vlc_tick_t)audioDelay;
+- (void)subtitlesDelayChanged:(vlc_tick_t)subtitlesDelay;
+- (void)recordingChanged:(BOOL)recording;
+- (void)stopActionChanged:(enum vlc_player_media_stopped_action)stoppedAction;
+
+/* video */
+- (void)fullscreenChanged:(BOOL)isFullscreen;
+- (void)wallpaperModeChanged:(BOOL)wallpaperModeValue;
+
+/* audio */
+- (void)volumeChanged:(float)volume;
+- (void)muteChanged:(BOOL)mute;
+ at end
+
+#pragma mark - player callback implementations
+
+static void cb_player_current_media_changed(vlc_player_t *p_player, input_item_t *p_newMediaItem, void *p_data)
+{
+    VLC_UNUSED(p_player);
+    dispatch_async(dispatch_get_main_queue(), ^{
+        VLCPlayerController *playerController = (__bridge VLCPlayerController *)p_data;
+        [playerController currentMediaItemChanged:p_newMediaItem];
+    });
+}
+
+static void cb_player_state_changed(vlc_player_t *p_player, enum vlc_player_state state, void *p_data)
+{
+    VLC_UNUSED(p_player);
+    dispatch_async(dispatch_get_main_queue(), ^{
+        VLCPlayerController *playerController = (__bridge VLCPlayerController *)p_data;
+        [playerController stateChanged:state];
+    });
+}
+
+static void cb_player_error_changed(vlc_player_t *p_player, enum vlc_player_error error, void *p_data)
+{
+    VLC_UNUSED(p_player);
+    dispatch_async(dispatch_get_main_queue(), ^{
+        VLCPlayerController *playerController = (__bridge VLCPlayerController *)p_data;
+        [playerController errorChanged:error];
+    });
+}
+
+static void cb_player_buffering(vlc_player_t *p_player, float newBufferValue, void *p_data)
+{
+    VLC_UNUSED(p_player);
+    dispatch_async(dispatch_get_main_queue(), ^{
+        VLCPlayerController *playerController = (__bridge VLCPlayerController *)p_data;
+        [playerController newBufferingValue:newBufferValue];
+    });
+}
+
+static void cb_player_rate_changed(vlc_player_t *p_player, float newRateValue, void *p_data)
+{
+    VLC_UNUSED(p_player);
+    dispatch_async(dispatch_get_main_queue(), ^{
+        VLCPlayerController *playerController = (__bridge VLCPlayerController *)p_data;
+        [playerController newRateValue:newRateValue];
+    });
+}
+
+static void cb_player_capabilities_changed(vlc_player_t *p_player, int newCapabilities, void *p_data)
+{
+    VLC_UNUSED(p_player);
+    dispatch_async(dispatch_get_main_queue(), ^{
+        VLCPlayerController *playerController = (__bridge VLCPlayerController *)p_data;
+        [playerController capabilitiesChanged:newCapabilities];
+    });
+}
+
+static void cb_player_position_changed(vlc_player_t *p_player, vlc_tick_t time, float position, void *p_data)
+{
+    VLC_UNUSED(p_player);
+    dispatch_async(dispatch_get_main_queue(), ^{
+        VLCPlayerController *playerController = (__bridge VLCPlayerController *)p_data;
+        [playerController position:position andTimeChanged:time];
+    });
+}
+
+static void cb_player_length_changed(vlc_player_t *p_player, vlc_tick_t newLength, void *p_data)
+{
+    VLC_UNUSED(p_player);
+    dispatch_async(dispatch_get_main_queue(), ^{
+        VLCPlayerController *playerController = (__bridge VLCPlayerController *)p_data;
+        [playerController lengthChanged:newLength];
+    });
+}
+
+static void cb_player_audio_delay_changed(vlc_player_t *p_player, vlc_tick_t newDelay, void *p_data)
+{
+    VLC_UNUSED(p_player);
+    dispatch_async(dispatch_get_main_queue(), ^{
+        VLCPlayerController *playerController = (__bridge VLCPlayerController *)p_data;
+        [playerController audioDelayChanged:newDelay];
+    });
+}
+
+static void cb_player_subtitle_delay_changed(vlc_player_t *p_player, vlc_tick_t newDelay, void *p_data)
+{
+    VLC_UNUSED(p_player);
+    dispatch_async(dispatch_get_main_queue(), ^{
+        VLCPlayerController *playerController = (__bridge VLCPlayerController *)p_data;
+        [playerController audioDelayChanged:newDelay];
+    });
+}
+
+static void cb_player_record_changed(vlc_player_t *p_player, bool recording, void *p_data)
+{
+    VLC_UNUSED(p_player);
+    dispatch_async(dispatch_get_main_queue(), ^{
+        VLCPlayerController *playerController = (__bridge VLCPlayerController *)p_data;
+        [playerController recordingChanged:recording];
+    });
+}
+
+static void cb_player_media_stopped_action_changed(vlc_player_t *p_player,
+                                                   enum vlc_player_media_stopped_action newAction,
+                                                   void *p_data)
+{
+
+}
+
+static const struct vlc_player_cbs player_callbacks = {
+    cb_player_current_media_changed,
+    cb_player_state_changed,
+    cb_player_error_changed,
+    cb_player_buffering,
+    cb_player_rate_changed,
+    cb_player_capabilities_changed,
+    cb_player_position_changed,
+    cb_player_length_changed,
+    NULL, //cb_player_track_list_changed,
+    NULL, //cb_player_track_selection_changed,
+    NULL, //cb_player_program_list_changed,
+    NULL, //cb_player_program_selection_changed,
+    NULL, //cb_player_titles_changed,
+    NULL, //cb_player_title_selection_changed,
+    NULL, //cb_player_chapter_selection_changed,
+    NULL, //cb_player_teletext_menu_changed,
+    NULL, //cb_player_teletext_enabled_changed,
+    NULL, //cb_player_teletext_page_changed,
+    NULL, //cb_player_teletext_transparency_changed,
+    cb_player_audio_delay_changed,
+    cb_player_subtitle_delay_changed,
+    NULL, //cb_player_associated_subs_fps_changed,
+    NULL, //cb_player_renderer_changed,
+    cb_player_record_changed,
+    NULL, //cb_player_signal_changed,
+    NULL, //cb_player_stats_changed,
+    NULL, //cb_player_atobloop_changed,
+    cb_player_media_stopped_action_changed,
+    NULL, //cb_player_item_meta_changed,
+    NULL, //cb_player_item_epg_changed,
+    NULL, //cb_player_subitems_changed,
+    NULL, //cb_player_vout_list_changed,
+};
+
+#pragma mark - video specific callback implementations
+
+static void cb_player_vout_fullscreen_changed(vlc_player_t *p_player, vout_thread_t *p_vout, bool isFullscreen, void *p_data)
+{
+    VLC_UNUSED(p_player); VLC_UNUSED(p_vout);
+    dispatch_async(dispatch_get_main_queue(), ^{
+        VLCPlayerController *playerController = (__bridge VLCPlayerController *)p_data;
+        [playerController fullscreenChanged:isFullscreen];
+    });
+}
+
+static void cb_player_vout_wallpaper_mode_changed(vlc_player_t *p_player, vout_thread_t *p_vout,  bool wallpaperModeEnabled, void *p_data)
+{
+    VLC_UNUSED(p_player); VLC_UNUSED(p_vout);
+    dispatch_async(dispatch_get_main_queue(), ^{
+        VLCPlayerController *playerController = (__bridge VLCPlayerController *)p_data;
+        [playerController wallpaperModeChanged:wallpaperModeEnabled];
+    });
+}
+
+static const struct vlc_player_vout_cbs player_vout_callbacks = {
+    cb_player_vout_fullscreen_changed,
+    cb_player_vout_wallpaper_mode_changed,
+};
+
+#pragma mark - video specific callback implementations
+
+static void cb_player_aout_volume_changed(vlc_player_t *p_player, float volume, void *p_data)
+{
+    VLC_UNUSED(p_player);
+    dispatch_async(dispatch_get_main_queue(), ^{
+        VLCPlayerController *playerController = (__bridge VLCPlayerController *)p_data;
+        [playerController volumeChanged:volume];
+    });
+}
+
+static void cb_player_aout_mute_changed(vlc_player_t *p_player, bool muted, void *p_data)
+{
+    VLC_UNUSED(p_player);
+    dispatch_async(dispatch_get_main_queue(), ^{
+        VLCPlayerController *playerController = (__bridge VLCPlayerController *)p_data;
+        [playerController muteChanged:muted];
+    });
+}
+
+static const struct vlc_player_aout_cbs player_aout_callbacks = {
+    cb_player_aout_volume_changed,
+    cb_player_aout_mute_changed,
+};
+
+#pragma mark - controller initialization
+
+ at implementation VLCPlayerController
+
+- (instancetype)initWithPlayer:(vlc_player_t *)player
+{
+    self = [super init];
+    if (self) {
+        _defaultNotificationCenter = [NSNotificationCenter defaultCenter];
+        _position = -1.f;
+        _time = VLC_TICK_INVALID;
+        _p_player = player;
+        vlc_player_Lock(_p_player);
+        // FIXME: initialize state machine here
+        _playerListenerID = vlc_player_AddListener(_p_player,
+                               &player_callbacks,
+                               (__bridge void *)self);
+        vlc_player_Unlock(_p_player);
+        _playerAoutListenerID = vlc_player_aout_AddListener(_p_player,
+                                                            &player_aout_callbacks,
+                                                            (__bridge void *)self);
+        _playerVoutListenerID = vlc_player_vout_AddListener(_p_player,
+                                                            &player_vout_callbacks,
+                                                            (__bridge void *)self);
+    }
+
+    return self;
+}
+
+- (void)dealloc
+{
+    if (_p_player) {
+        if (_playerListenerID) {
+            vlc_player_Lock(_p_player);
+            vlc_player_RemoveListener(_p_player, _playerListenerID);
+            vlc_player_Unlock(_p_player);
+        }
+        if (_playerAoutListenerID) {
+            vlc_player_aout_RemoveListener(_p_player, _playerAoutListenerID);
+        }
+        if (_playerVoutListenerID) {
+            vlc_player_vout_RemoveListener(_p_player, _playerVoutListenerID);
+        }
+    }
+}
+
+#pragma mark - playback control methods
+
+- (int)start
+{
+    vlc_player_Lock(_p_player);
+    int ret = vlc_player_Start(_p_player);
+    vlc_player_Unlock(_p_player);
+    return ret;
+}
+
+- (void)startInPausedState:(BOOL)startPaused
+{
+    vlc_player_Lock(_p_player);
+    vlc_player_SetStartPaused(_p_player, startPaused);
+    vlc_player_Unlock(_p_player);
+}
+
+- (void)pause
+{
+    vlc_player_Lock(_p_player);
+    vlc_player_Pause(_p_player);
+    vlc_player_Unlock(_p_player);
+}
+
+- (void)resume
+{
+    vlc_player_Lock(_p_player);
+    vlc_player_Resume(_p_player);
+    vlc_player_Unlock(_p_player);
+}
+
+- (void)stop
+{
+    vlc_player_Lock(_p_player);
+    vlc_player_Stop(_p_player);
+    vlc_player_Unlock(_p_player);
+}
+
+- (void)stopActionChanged:(enum vlc_player_media_stopped_action)stoppedAction
+{
+    _actionAfterStop = stoppedAction;
+}
+
+- (void)setActionAfterStop:(enum vlc_player_media_stopped_action)actionAfterStop
+{
+    vlc_player_Lock(_p_player);
+    vlc_player_SetMediaStoppedAction(_p_player, actionAfterStop);
+    vlc_player_Unlock(_p_player);
+}
+
+- (void)nextVideoFrame
+{
+    vlc_player_Lock(_p_player);
+    vlc_player_NextVideoFrame(_p_player);
+    vlc_player_Unlock(_p_player);
+}
+
+#pragma mark - player callback delegations
+
+- (input_item_t *)currentMedia
+{
+    input_item_t *inputItem;
+    vlc_player_Lock(_p_player);
+    inputItem = vlc_player_GetCurrentMedia(_p_player);
+    vlc_player_Unlock(_p_player);
+    return inputItem;
+}
+
+- (int)setCurrentMedia:(input_item_t *)currentMedia
+{
+    if (currentMedia == NULL) {
+        return VLC_ENOITEM;
+    }
+    vlc_player_Lock(_p_player);
+    int ret = vlc_player_SetCurrentMedia(_p_player, currentMedia);
+    vlc_player_Unlock(_p_player);
+    return ret;
+}
+
+- (void)currentMediaItemChanged:(input_item_t *)newMediaItem
+{
+    [_defaultNotificationCenter postNotificationName:VLCPlayerCurrentMediaItemChanged
+                                              object:self
+                                            userInfo:@{VLCPlayerCurrentMediaItem:[NSValue valueWithPointer:newMediaItem]}];
+}
+
+- (void)stateChanged:(enum vlc_player_state)state
+{
+    /* 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;
+    [_defaultNotificationCenter postNotificationName:VLCPlayerStateChanged
+                                              object:self];
+}
+
+- (void)errorChanged:(enum vlc_player_error)error
+{
+    /* instead of using vlc_player_GetError, we cache the error and provide it through a synthesized getter
+     * as the direct call might not reflect the actual error due the asynchronous API nature */
+    _error = error;
+    [_defaultNotificationCenter postNotificationName:VLCPlayerErrorChanged
+                                              object:self];
+}
+
+- (void)newBufferingValue:(float)bufferValue
+{
+    _bufferFill = bufferValue;
+    [_defaultNotificationCenter postNotificationName:VLCPlayerBufferChanged
+                                              object:self
+                                            userInfo:@{VLCPlayerBufferFill : @(bufferValue)}];
+}
+
+- (void)newRateValue:(float)rateValue
+{
+    _playbackRate = rateValue;
+    [_defaultNotificationCenter postNotificationName:VLCPlayerRateChanged
+                                              object:self];
+}
+
+- (void)setPlaybackRate:(float)playbackRate
+{
+    vlc_player_Lock(_p_player);
+    vlc_player_ChangeRate(_p_player, playbackRate);
+    vlc_player_Unlock(_p_player);
+}
+
+- (void)incrementPlaybackRate
+{
+    vlc_player_Lock(_p_player);
+    vlc_player_IncrementRate(_p_player);
+    vlc_player_Unlock(_p_player);
+}
+
+- (void)decrementPlaybackRate
+{
+    vlc_player_Lock(_p_player);
+    vlc_player_DecrementRate(_p_player);
+    vlc_player_Unlock(_p_player);
+}
+
+- (void)capabilitiesChanged:(int)newCapabilities
+{
+    _seekable = newCapabilities & VLC_INPUT_CAPABILITIES_SEEKABLE;
+    _rewindable = newCapabilities & VLC_INPUT_CAPABILITIES_REWINDABLE;
+    _pausable = newCapabilities & VLC_INPUT_CAPABILITIES_PAUSEABLE;
+    _recordable = newCapabilities & VLC_INPUT_CAPABILITIES_RECORDABLE;
+    _rateChangable = newCapabilities & VLC_INPUT_CAPABILITIES_CHANGE_RATE;
+    [_defaultNotificationCenter postNotificationName:VLCPlayerCapabilitiesChanged
+                                              object:self];
+}
+
+- (void)position:(float)position andTimeChanged:(vlc_tick_t)time
+{
+    _position = position;
+    _time = time;
+    [_defaultNotificationCenter postNotificationName:VLCPlayerTimeAndPositionChanged
+                                              object:self];
+}
+
+- (void)setTimeFast:(vlc_tick_t)time
+{
+    vlc_player_Lock(_p_player);
+    vlc_player_SeekByTime(_p_player, time, VLC_PLAYER_SEEK_FAST, VLC_PLAYER_WHENCE_ABSOLUTE);
+    vlc_player_Unlock(_p_player);
+}
+
+- (void)setTimePrecise:(vlc_tick_t)time
+{
+    vlc_player_Lock(_p_player);
+    vlc_player_SeekByTime(_p_player, time, VLC_PLAYER_SEEK_PRECISE, VLC_PLAYER_WHENCE_ABSOLUTE);
+    vlc_player_Unlock(_p_player);
+}
+
+- (void)setPositionFast:(float)position
+{
+    vlc_player_Lock(_p_player);
+    vlc_player_SeekByPos(_p_player, position, VLC_PLAYER_SEEK_FAST, VLC_PLAYER_WHENCE_ABSOLUTE);
+    vlc_player_Unlock(_p_player);
+}
+
+- (void)setPositionPrecise:(float)position
+{
+    vlc_player_Lock(_p_player);
+    vlc_player_SeekByPos(_p_player, position, VLC_PLAYER_SEEK_PRECISE, VLC_PLAYER_WHENCE_ABSOLUTE);
+    vlc_player_Unlock(_p_player);
+}
+
+- (void)lengthChanged:(vlc_tick_t)length
+{
+    _length = length;
+    [_defaultNotificationCenter postNotificationName:VLCPlayerLengthChanged
+                                              object:self];
+}
+
+- (void)audioDelayChanged:(vlc_tick_t)audioDelay
+{
+    _audioDelay = audioDelay;
+    [_defaultNotificationCenter postNotificationName:VLCPlayerAudioDelayChanged
+                                              object:self];
+}
+
+- (void)setAudioDelay:(vlc_tick_t)audioDelay
+{
+    vlc_player_Lock(_p_player);
+    vlc_player_SetAudioDelay(_p_player, audioDelay, VLC_PLAYER_WHENCE_ABSOLUTE);
+    vlc_player_Unlock(_p_player);
+}
+
+- (void)subtitlesDelayChanged:(vlc_tick_t)subtitlesDelay
+{
+    _subtitlesDelay = subtitlesDelay;
+    [_defaultNotificationCenter postNotificationName:VLCPlayerSubtitlesDelayChanged
+                                              object:self];
+}
+
+- (void)setSubtitlesDelay:(vlc_tick_t)subtitlesDelay
+{
+    vlc_player_Lock(_p_player);
+    vlc_player_SetSubtitleDelay(_p_player, subtitlesDelay, VLC_PLAYER_WHENCE_ABSOLUTE);
+    vlc_player_Unlock(_p_player);
+}
+
+- (void)recordingChanged:(BOOL)recording
+{
+    _enableRecording = recording;
+    [_defaultNotificationCenter postNotificationName:VLCPlayerRecordingChanged
+                                              object:self];
+}
+
+- (void)setEnableRecording:(BOOL)enableRecording
+{
+    vlc_player_Lock(_p_player);
+    vlc_player_SetRecordingEnabled(_p_player, enableRecording);
+    vlc_player_Unlock(_p_player);
+}
+
+#pragma mark - video specific delegation
+
+- (void)fullscreenChanged:(BOOL)isFullscreen
+{
+    _fullscreen = isFullscreen;
+    [_defaultNotificationCenter postNotificationName:VLCPlayerFullscreenChanged
+                                              object:self];
+}
+
+- (void)setFullscreen:(BOOL)fullscreen
+{
+    vlc_player_vout_SetFullscreen(_p_player, fullscreen);
+}
+
+- (void)wallpaperModeChanged:(BOOL)wallpaperModeValue
+{
+    _wallpaperMode = wallpaperModeValue;
+    [_defaultNotificationCenter postNotificationName:VLCPlayerWallpaperModeChanged
+                                              object:self];
+}
+
+- (void)setWallpaperMode:(BOOL)wallpaperMode
+{
+    vlc_player_vout_SetWallpaperModeEnabled(_p_player, wallpaperMode);
+}
+
+#pragma mark - audio specific delegation
+
+- (void)volumeChanged:(float)volume
+{
+    _volume = volume;
+    [_defaultNotificationCenter postNotificationName:VLCPlayerVolumeChanged
+                                              object:self];
+}
+
+- (void)setVolume:(float)volume
+{
+    vlc_player_aout_SetVolume(_p_player, volume);
+}
+
+- (void)muteChanged:(BOOL)mute
+{
+    _mute = mute;
+    [_defaultNotificationCenter postNotificationName:VLCPlayerMuteChanged
+                                              object:self];
+}
+
+- (void)setMute:(BOOL)mute
+{
+    vlc_player_aout_Mute(_p_player, mute);
+}
+
+ at end
diff --git a/modules/gui/macosx/playlist/VLCPlaylistController.m b/modules/gui/macosx/playlist/VLCPlaylistController.m
index 9108405c62..d28b0a2554 100644
--- a/modules/gui/macosx/playlist/VLCPlaylistController.m
+++ b/modules/gui/macosx/playlist/VLCPlaylistController.m
@@ -63,7 +63,6 @@ cb_playlist_items_reset(vlc_playlist_t *playlist,
                         size_t numberOfItems,
                         void *p_data)
 {
-    VLC_UNUSED(numberOfItems);
     NSMutableArray *array = [NSMutableArray arrayWithCapacity:numberOfItems];
     for (size_t i = 0; i < numberOfItems; i++) {
         VLCPlaylistItem *item = [[VLCPlaylistItem alloc] initWithPlaylistItem:items[i]];




More information about the vlc-commits mailing list