vlc | branch: master | Felix Paul Kühne <[email protected]> | 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; + +@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 + */ +@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 + */ +@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 + */ +@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 + */ +@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 + */ +@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 + */ +@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 + */ +@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 + */ +@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 + */ +@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 + */ +@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 + */ +@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 + */ +@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 + */ +@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 + */ +@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 + */ +@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 + */ +@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 + */ +@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 + */ +@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 + */ +@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 + */ +@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 + */ +@property (readwrite, nonatomic) BOOL mute; + +@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"; + +@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; +@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 + +@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); +} + +@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]]; _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
