Commit 64a43503 authored by Felix Paul Kühne's avatar Felix Paul Kühne

macosx: add remote control service and export now playing metadata

Fixes #17727

Note that out-of-rate position changes within VLC are not yet communicated to the OS
parent 256c7408
......@@ -120,6 +120,7 @@
6BF56C3E1FCF00AF004A411A /* audiotoolbox_midi.c in Sources */ = {isa = PBXBuildFile; fileRef = 6BF56C3D1FCF00AF004A411A /* audiotoolbox_midi.c */; };
6BF5C5041EFE66EF008A9C12 /* VLCHUDTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BF5C5031EFE66EF008A9C12 /* VLCHUDTableView.m */; };
6BF5C5071EFE7E58008A9C12 /* VLCTintedImageButtonCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BF5C5061EFE7E58008A9C12 /* VLCTintedImageButtonCell.m */; };
7DD2F5C52081B73B007EE187 /* VLCRemoteControlService.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DD2F5C42081B73B007EE187 /* VLCRemoteControlService.m */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
......@@ -485,6 +486,8 @@
7DB65D5218ABD6380053B874 /* VLCAddonsWindowController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VLCAddonsWindowController.h; sourceTree = "<group>"; };
7DB65D5318ABD6380053B874 /* VLCAddonsWindowController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VLCAddonsWindowController.m; sourceTree = "<group>"; };
7DBB06631CC2314D004C74D2 /* caopengllayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = caopengllayer.m; path = ../../../modules/video_output/caopengllayer.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>"; };
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>"; };
......@@ -689,6 +692,8 @@
7D871D391B5E684D000B56C0 /* helpers.h */,
7DF812ED1B555A340052293C /* VLCInputManager.h */,
7DF812EE1B555A340052293C /* VLCInputManager.m */,
7DD2F5C32081B73B007EE187 /* VLCRemoteControlService.h */,
7DD2F5C42081B73B007EE187 /* VLCRemoteControlService.m */,
7D871D371B5E6844000B56C0 /* VLCMain+OldPrefs.h */,
7D871D381B5E6844000B56C0 /* VLCMain+OldPrefs.m */,
8ED6C27C03E2EB1C0059A3A7 /* VLCMain.h */,
......@@ -1309,7 +1314,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;
......@@ -1395,6 +1400,7 @@
6BF5C5041EFE66EF008A9C12 /* VLCHUDTableView.m in Sources */,
6BBB05E01EEFF165003A1019 /* VLCHUDTableCornerView.m in Sources */,
1C31139D1E508C6900D4DD76 /* VLCControlsBarCommon.m in Sources */,
7DD2F5C52081B73B007EE187 /* VLCRemoteControlService.m in Sources */,
1C31139F1E508C6900D4DD76 /* VLCMainWindowControlsBar.m in Sources */,
1C3113A11E508C6900D4DD76 /* VLCConvertAndSaveWindowController.m in Sources */,
1C3113A31E508C6900D4DD76 /* VLCCoreDialogProvider.m in Sources */,
......@@ -1657,7 +1663,7 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Default;
};
C2F2A6EA09588F1B00018C74 /* Build configuration list for PBXProject "vlc" */ = {
C2F2A6EA09588F1B00018C74 /* Build configuration list for PBXProject "VLC" */ = {
isa = XCConfigurationList;
buildConfigurations = (
C2F2A6EB09588F1B00018C74 /* Development */,
......
/*****************************************************************************
* CompatibilityFixes.h: MacOS X interface module
*****************************************************************************
* Copyright (C) 2011-2017 VLC authors and VideoLAN
* Copyright (C) 2011-2018 VLC authors and VideoLAN
* $Id$
*
* Authors: Felix Paul Kühne <fkuehne -at- videolan -dot- org>
......@@ -32,9 +32,9 @@
#define OSX_YOSEMITE_AND_HIGHER (NSAppKitVersionNumber >= 1334)
#define OSX_EL_CAPITAN_AND_HIGHER (NSAppKitVersionNumber >= 1404)
#define OSX_SIERRA_AND_HIGHER (NSAppKitVersionNumber >= 1485)
#define OSX_SIERRA_DOT_TWO_AND_HIGHER (NSAppKitVersionNumber >= 1504.76) // this is needed to check for MPRemoteCommandCenter
#define OSX_HIGH_SIERRA_AND_HIGHER (NSAppKitVersionNumber >= 1560)
// Sierra only APIs
#ifndef MAC_OS_X_VERSION_10_12
......@@ -56,5 +56,51 @@ typedef NSUInteger NSWindowStyleMask;
#endif
void swapoutOverride(Class _Nonnull cls, SEL _Nonnull selector);
#ifndef MAC_OS_X_VERSION_10_12_2
typedef NS_ENUM(NSUInteger, MPNowPlayingInfoMediaType) {
MPNowPlayingInfoMediaTypeNone = 0,
MPNowPlayingInfoMediaTypeAudio,
MPNowPlayingInfoMediaTypeVideo,
};
typedef NS_ENUM(NSUInteger, MPNowPlayingPlaybackState) {
MPNowPlayingPlaybackStateUnknown = 0,
MPNowPlayingPlaybackStatePlaying,
MPNowPlayingPlaybackStatePaused,
MPNowPlayingPlaybackStateStopped,
MPNowPlayingPlaybackStateInterrupted
};
NSString * const MPNowPlayingInfoPropertyElapsedPlaybackTime;
NSString * const MPNowPlayingInfoPropertyPlaybackRate;
NSString * const MPNowPlayingInfoPropertyDefaultPlaybackRate;
NSString * const MPNowPlayingInfoPropertyPlaybackQueueIndex;
NSString * const MPNowPlayingInfoPropertyPlaybackQueueCount;
NSString * const MPNowPlayingInfoPropertyChapterNumber;
NSString * const MPNowPlayingInfoPropertyChapterCount
NSString * const MPNowPlayingInfoPropertyIsLiveStream;
NSString * const MPNowPlayingInfoPropertyAvailableLanguageOptions;
NSString * const MPNowPlayingInfoPropertyCurrentLanguageOptions;
NSString * const MPNowPlayingInfoCollectionIdentifier;
NSString * const MPNowPlayingInfoPropertyExternalContentIdentifier;
NSString * const MPNowPlayingInfoPropertyExternalUserProfileIdentifier
NSString * const MPNowPlayingInfoPropertyServiceIdentifier;
NSString * const MPNowPlayingInfoPropertyPlaybackProgress
NSString * const MPNowPlayingInfoPropertyMediaType
NSString * const MPNowPlayingInfoPropertyAssetURL;
NSString * const MPNowPlayingInfoPropertyCurrentPlaybackDate;
@interface MPNowPlayingInfoCenter : NSObject
+ (MPNowPlayingInfoCenter *)defaultCenter;
+ (instancetype)new NS_UNAVAILABLE;
- (instancetype)init NS_UNAVAILABLE;
@property (nonatomic, copy, nullable) NSDictionary<NSString *, id> *nowPlayingInfo;
@property (nonatomic) MPNowPlayingPlaybackState playbackState MP_API(macos(10.12.2));
@end
#endif
void swapoutOverride(Class _Nonnull cls, SEL _Nonnull selector);
......@@ -6,7 +6,7 @@ libmacosx_plugin_la_LDFLAGS = $(AM_LDFLAGS) -rpath '$(guidir)' \
-Wl,-framework,AVFoundation -Wl,-framework,CoreMedia -Wl,-framework,IOKit \
-Wl,-framework,AddressBook -Wl,-framework,WebKit -Wl,-framework,CoreAudio \
-Wl,-framework,SystemConfiguration -Wl,-framework,ScriptingBridge \
-Wl,-framework,QuartzCore
-Wl,-framework,QuartzCore -Wl,-framework,MediaPlayer
if HAVE_SPARKLE
libmacosx_plugin_la_LDFLAGS += -Wl,-framework,Sparkle
......@@ -78,6 +78,7 @@ libmacosx_plugin_la_SOURCES = \
gui/macosx/VLCHUDTableView.h gui/macosx/VLCHUDTableView.m \
gui/macosx/VLCHUDTableCornerView.h gui/macosx/VLCHUDTableCornerView.m \
gui/macosx/VLCInputManager.h gui/macosx/VLCInputManager.m \
gui/macosx/VLCRemoteControlService.h gui/macosx/VLCRemoteControlService.m \
gui/macosx/VLCMainWindow.h gui/macosx/VLCMainWindow.m \
gui/macosx/VLCRendererDiscovery.h gui/macosx/VLCRendererDiscovery.m \
gui/macosx/VLCRendererItem.h gui/macosx/VLCRendererItem.m \
......
/*****************************************************************************
* CoreInteraction.h: MacOS X interface module
*****************************************************************************
* Copyright (C) 2011-2015 Felix Paul Kühne
* Copyright (C) 2011-2018 Felix Paul Kühne
* $Id$
*
* Authors: Felix Paul Kühne <fkuehne -at- videolan -dot- org>
......@@ -36,6 +36,7 @@
@property (readonly) NSString * nameOfCurrentPlaylistItem;
@property (nonatomic, readwrite) BOOL mute;
- (void)play;
- (void)playOrPause;
- (void)pause;
- (void)stop;
......@@ -55,6 +56,7 @@
- (void)backwardMedium;
- (void)forwardLong;
- (void)backwardLong;
- (void)jumpToTime:(mtime_t)time;
- (void)repeatOne;
- (void)repeatAll;
......
/*****************************************************************************
* CoreInteraction.m: MacOS X interface module
*****************************************************************************
* Copyright (C) 2011-2015 Felix Paul Kühne
* Copyright (C) 2011-2018 Felix Paul Kühne
* $Id$
*
* Authors: Felix Paul Kühne <fkuehne -at- videolan -dot- org>
......@@ -129,6 +129,13 @@ static int BossCallback(vlc_object_t *p_this, const char *psz_var,
#pragma mark - Playback Controls
- (void)play
{
playlist_t *p_playlist = pl_Get(getIntf());
playlist_Play(p_playlist);
}
- (void)playOrPause
{
input_thread_t *p_input = pl_CurrentInput(getIntf());
......@@ -532,6 +539,16 @@ static int BossCallback(vlc_object_t *p_this, const char *psz_var,
}
}
- (void)jumpToTime:(mtime_t)time
{
input_thread_t * p_input = pl_CurrentInput(getIntf());
if (p_input) {
mtime_t currentTime = var_GetInteger(p_input, "time");
var_SetInteger(p_input, "time", time);
vlc_object_release(p_input);
}
}
- (void)volumeUp
{
intf_thread_t *p_intf = getIntf();
......
/*****************************************************************************
* VLCInputManager.m: MacOS X interface module
*****************************************************************************
* Copyright (C) 2015 VLC authors and VideoLAN
* Copyright (C) 2015-2018 VLC authors and VideoLAN
* $Id$
*
* This program is free software; you can redistribute it and/or modify
......@@ -34,10 +34,13 @@
#import "VLCResumeDialogController.h"
#import "VLCTrackSynchronizationWindowController.h"
#import "VLCVoutView.h"
#import "VLCRemoteControlService.h"
#import "iTunes.h"
#import "Spotify.h"
#import <MediaPlayer/MediaPlayer.h>
#pragma mark Callbacks
static int InputThreadChanged(vlc_object_t *p_this, const char *psz_var,
......@@ -155,6 +158,9 @@ static int InputEvent(vlc_object_t *p_this, const char *psz_var,
BOOL b_has_itunes_paused;
BOOL b_has_spotify_paused;
/* remote control support */
VLCRemoteControlService *_remoteControlService;
NSTimer *hasEndedTimer;
}
@end
......@@ -182,6 +188,8 @@ static int InputEvent(vlc_object_t *p_this, const char *psz_var,
informInputChangedQueue = dispatch_queue_create("org.videolan.vlc.inputChangedQueue", DISPATCH_QUEUE_SERIAL);
_remoteControlService = [[VLCRemoteControlService alloc] init];
[_remoteControlService subscribeToRemoteCommands];
}
return self;
}
......@@ -196,6 +204,8 @@ static int InputEvent(vlc_object_t *p_this, const char *psz_var,
- (void)deinit
{
msg_Dbg(getIntf(), "Deinitializing input manager");
[_remoteControlService unsubscribeFromRemoteCommands];
if (p_current_input) {
/* continue playback where you left off */
[self storePlaybackPositionForItem:p_current_input];
......@@ -283,7 +293,6 @@ static int InputEvent(vlc_object_t *p_this, const char *psz_var,
return;
}
intf_thread_t *p_intf = getIntf();
int state = -1;
if (p_current_input) {
state = var_GetInteger(p_current_input, "state");
......@@ -304,14 +313,29 @@ static int InputEvent(vlc_object_t *p_this, const char *psz_var,
[[o_main mainMenu] setPause];
[[o_main mainWindow] setPause];
if (OSX_SIERRA_DOT_TWO_AND_HIGHER) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wpartial-availability"
[MPNowPlayingInfoCenter defaultCenter].playbackState = MPNowPlayingPlaybackStatePlaying;
#pragma clang diagnostic pop
}
} else {
[[o_main mainMenu] setSubmenusEnabled: FALSE];
[[o_main mainMenu] setPlay];
[[o_main mainWindow] setPlay];
if (state == PAUSE_S)
if (state == PAUSE_S) {
[self releaseSleepBlockers];
if (OSX_SIERRA_DOT_TWO_AND_HIGHER) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wpartial-availability"
[MPNowPlayingInfoCenter defaultCenter].playbackState = MPNowPlayingPlaybackStatePaused;
#pragma clang diagnostic pop
}
}
if (state == END_S || state == -1) {
/* continue playback where you left off */
if (p_current_input)
......@@ -325,6 +349,13 @@ static int InputEvent(vlc_object_t *p_this, const char *psz_var,
selector: @selector(onPlaybackHasEnded:)
userInfo: nil
repeats: NO];
if (OSX_SIERRA_DOT_TWO_AND_HIGHER) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wpartial-availability"
[MPNowPlayingInfoCenter defaultCenter].playbackState = MPNowPlayingPlaybackStateStopped;
#pragma clang diagnostic pop
}
}
}
......@@ -490,6 +521,43 @@ static int InputEvent(vlc_object_t *p_this, const char *psz_var,
[[[o_main playlist] model] updateItem:p_input_item];
[[[VLCMain sharedInstance] currentMediaInfoPanel] updatePanelWithItem:p_input_item];
if (!OSX_SIERRA_DOT_TWO_AND_HIGHER) {
return;
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wpartial-availability"
if (!p_input_item) {
return;
}
NSMutableDictionary *currentlyPlayingTrackInfo = [NSMutableDictionary dictionary];
currentlyPlayingTrackInfo[MPMediaItemPropertyPlaybackDuration] = @(input_item_GetDuration(p_input_item) / CLOCK_FREQ);
currentlyPlayingTrackInfo[MPNowPlayingInfoPropertyElapsedPlaybackTime] = @(var_GetInteger(p_current_input, "time"));
currentlyPlayingTrackInfo[MPNowPlayingInfoPropertyPlaybackRate] = @(var_GetFloat(p_current_input, "rate"));
char *psz_title = input_item_GetTitle(p_input_item);
if (!psz_title)
psz_title = input_item_GetName(p_input_item);
currentlyPlayingTrackInfo[MPMediaItemPropertyTitle] = toNSStr(psz_title);
FREENULL(psz_title);
char *psz_artist = input_item_GetArtist(p_input_item);
currentlyPlayingTrackInfo[MPMediaItemPropertyArtist] = toNSStr(psz_artist);
FREENULL(psz_artist);
char *psz_album = input_item_GetAlbum(p_input_item);
currentlyPlayingTrackInfo[MPMediaItemPropertyAlbumTitle] = toNSStr(psz_album);
FREENULL(psz_album);
char *psz_track_number = input_item_GetTrackNumber(p_input_item);
currentlyPlayingTrackInfo[MPMediaItemPropertyAlbumTrackNumber] = toNSStr(psz_track_number);
FREENULL(psz_track_number);
[MPNowPlayingInfoCenter defaultCenter].nowPlayingInfo = currentlyPlayingTrackInfo;
#pragma clang diagnostic pop
}
- (void)updateMainWindow
......
/*****************************************************************************
* VLCRemoteControlService.h: MacOS X interface module
*****************************************************************************
* Copyright (C) 2017, 2018 VLC authors and VideoLAN
* $Id$
*
* Authors: Carola Nitz <nitz.carola # gmail.com>
* Felix Paul Kühne <fkuehne # videolan.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 <Cocoa/Cocoa.h>
@interface VLCRemoteControlService : NSObject
- (void)subscribeToRemoteCommands;
- (void)unsubscribeFromRemoteCommands;
@end
/*****************************************************************************
* VLCRemoteControlService.m: MacOS X interface module
*****************************************************************************
* Copyright (C) 2017, 2018 VLC authors and VideoLAN
* $Id$
*
* Authors: Carola Nitz <nitz.carola # gmail.com>
* Felix Paul Kühne <fkuehne # videolan.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 "VLCRemoteControlService.h"
#import "VLCCoreInteraction.h"
#import "VLCMain.h"
#import <MediaPlayer/MediaPlayer.h>
#import "CompatibilityFixes.h"
#define kVLCSettingPlaybackForwardSkipLength @(60)
#define kVLCSettingPlaybackBackwardSkipLength @(60)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wpartial-availability"
@implementation VLCRemoteControlService
static inline NSArray * RemoteCommandCenterCommandsToHandle()
{
MPRemoteCommandCenter *cc = [MPRemoteCommandCenter sharedCommandCenter];
NSMutableArray *commands = [NSMutableArray arrayWithObjects:
cc.playCommand,
cc.pauseCommand,
cc.stopCommand,
cc.togglePlayPauseCommand,
cc.nextTrackCommand,
cc.previousTrackCommand,
cc.skipForwardCommand,
cc.skipBackwardCommand,
cc.changePlaybackPositionCommand,
nil];
return [commands copy];
}
- (void)subscribeToRemoteCommands
{
if (!OSX_SIERRA_DOT_TWO_AND_HIGHER) {
return;
}
MPRemoteCommandCenter *commandCenter = [MPRemoteCommandCenter sharedCommandCenter];
//Enable when you want to support these
commandCenter.ratingCommand.enabled = NO;
commandCenter.likeCommand.enabled = NO;
commandCenter.dislikeCommand.enabled = NO;
commandCenter.bookmarkCommand.enabled = NO;
commandCenter.enableLanguageOptionCommand.enabled = NO;
commandCenter.disableLanguageOptionCommand.enabled = NO;
commandCenter.changeRepeatModeCommand.enabled = NO;
commandCenter.changeShuffleModeCommand.enabled = NO;
commandCenter.seekForwardCommand.enabled = NO;
commandCenter.seekBackwardCommand.enabled = NO;
commandCenter.skipForwardCommand.preferredIntervals = @[kVLCSettingPlaybackForwardSkipLength];
commandCenter.skipBackwardCommand.preferredIntervals = @[kVLCSettingPlaybackBackwardSkipLength];
for (MPRemoteCommand *command in RemoteCommandCenterCommandsToHandle()) {
[command addTarget:self action:@selector(remoteCommandEvent:)];
}
}
- (void)unsubscribeFromRemoteCommands
{
if (!OSX_SIERRA_DOT_TWO_AND_HIGHER) {
return;
}
[MPNowPlayingInfoCenter defaultCenter].nowPlayingInfo = nil;
for (MPRemoteCommand *command in RemoteCommandCenterCommandsToHandle()) {
[command removeTarget:self];
}
}
- (MPRemoteCommandHandlerStatus )remoteCommandEvent:(MPRemoteCommandEvent *)event
{
MPRemoteCommandCenter *cc = [MPRemoteCommandCenter sharedCommandCenter];
VLCCoreInteraction *coreInteraction = [VLCCoreInteraction sharedInstance];
if (event.command == cc.playCommand) {
[coreInteraction play];
return MPRemoteCommandHandlerStatusSuccess;
}
if (event.command == cc.pauseCommand) {
[coreInteraction pause];
return MPRemoteCommandHandlerStatusSuccess;
}
if (event.command == cc.stopCommand) {
[coreInteraction stop];
return MPRemoteCommandHandlerStatusSuccess;
}
if (event.command == cc.togglePlayPauseCommand) {
[coreInteraction playOrPause];
return MPRemoteCommandHandlerStatusSuccess;
}
if (event.command == cc.nextTrackCommand) {
[coreInteraction next];
return MPRemoteCommandHandlerStatusSuccess;
}
if (event.command == cc.previousTrackCommand) {
[coreInteraction previous];
return MPRemoteCommandHandlerStatusSuccess;
}
if (event.command == cc.skipForwardCommand) {
[coreInteraction forwardMedium];
return MPRemoteCommandHandlerStatusSuccess;
}
if (event.command == cc.skipBackwardCommand) {
[coreInteraction backwardMedium];
return MPRemoteCommandHandlerStatusSuccess;
}
if (event.command == cc.changePlaybackPositionCommand) {
MPChangePlaybackPositionCommandEvent *positionEvent = (MPChangePlaybackPositionCommandEvent *)event;
[coreInteraction jumpToTime:positionEvent.positionTime * CLOCK_FREQ];
return MPRemoteCommandHandlerStatusSuccess;
}
NSAssert(NO, @"remote control event not handled");
msg_Dbg(getIntf(), "%s Wasn't able to handle remote control event: %s",__PRETTY_FUNCTION__,[event.description UTF8String]);
return MPRemoteCommandHandlerStatusCommandFailed;
}
@end
#pragma clang diagnostic pop
......@@ -24,11 +24,11 @@
#import "CompatibilityFixes.h"
#import "misc.h"
#import "VLCMain.h" /* VLCApplication */
#import "VLCMainWindow.h"
#import "VLCMainMenu.h"
#import "VLCControlsBarCommon.h"
#import "VLCCoreInteraction.h"
#import "VLCStringUtility.h"
#import <vlc_actions.h>
/*****************************************************************************
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment