|
@@ -6,10 +6,6 @@
|
|
|
#include "SPMediaKeyTap.h"
|
|
|
#include "QsLog.h"
|
|
|
|
|
|
-#import <dlfcn.h>
|
|
|
-
|
|
|
-#import <MediaPlayer/MediaPlayer.h>
|
|
|
-
|
|
|
@interface MediaKeysDelegate : NSObject
|
|
|
{
|
|
|
SPMediaKeyTap* keyTap;
|
|
@@ -25,28 +21,11 @@
|
|
|
self = [super init];
|
|
|
if (self) {
|
|
|
input = input_;
|
|
|
- if (NSClassFromString(@"MPRemoteCommandCenter")) {
|
|
|
- MPRemoteCommandCenter* center = [MPRemoteCommandCenter sharedCommandCenter];
|
|
|
-#define CONFIG_CMD(name) \
|
|
|
- [center.name ## Command addTarget:self action:@selector(gotCommand:)]
|
|
|
- CONFIG_CMD(play);
|
|
|
- CONFIG_CMD(pause);
|
|
|
- CONFIG_CMD(togglePlayPause);
|
|
|
- CONFIG_CMD(stop);
|
|
|
- CONFIG_CMD(nextTrack);
|
|
|
- CONFIG_CMD(previousTrack);
|
|
|
- CONFIG_CMD(seekForward);
|
|
|
- CONFIG_CMD(seekBackward);
|
|
|
- CONFIG_CMD(skipForward);
|
|
|
- CONFIG_CMD(skipBackward);
|
|
|
- [center.changePlaybackPositionCommand addTarget:self action:@selector(gotPlaybackPosition:)];
|
|
|
- } else {
|
|
|
- keyTap = [[SPMediaKeyTap alloc] initWithDelegate:self];
|
|
|
- if ([SPMediaKeyTap usesGlobalMediaKeyTap])
|
|
|
- [keyTap startWatchingMediaKeys];
|
|
|
- else
|
|
|
- QLOG_WARN() << "Could not grab global media keys";
|
|
|
- }
|
|
|
+ keyTap = [[SPMediaKeyTap alloc] initWithDelegate:self];
|
|
|
+ if ([SPMediaKeyTap usesGlobalMediaKeyTap])
|
|
|
+ [keyTap startWatchingMediaKeys];
|
|
|
+ else
|
|
|
+ QLOG_WARN() << "Could not grab global media keys";
|
|
|
}
|
|
|
return self;
|
|
|
}
|
|
@@ -56,38 +35,6 @@
|
|
|
[super dealloc];
|
|
|
}
|
|
|
|
|
|
--(MPRemoteCommandHandlerStatus)gotCommand:(MPRemoteCommandEvent *)event
|
|
|
-{
|
|
|
- QString keyPressed;
|
|
|
- MPRemoteCommand* command = [event command];
|
|
|
-
|
|
|
-#define CMD(name) [MPRemoteCommandCenter sharedCommandCenter].name ## Command
|
|
|
- if (command == CMD(play)) {
|
|
|
- keyPressed = INPUT_KEY_PLAY;
|
|
|
- } else if (command == CMD(pause)) {
|
|
|
- keyPressed = INPUT_KEY_PAUSE;
|
|
|
- } else if (command == CMD(togglePlayPause)) {
|
|
|
- keyPressed = INPUT_KEY_PLAY_PAUSE;
|
|
|
- } else if (command == CMD(stop)) {
|
|
|
- keyPressed = INPUT_KEY_STOP;
|
|
|
- } else if (command == CMD(nextTrack)) {
|
|
|
- keyPressed = INPUT_KEY_NEXT;
|
|
|
- } else if (command == CMD(previousTrack)) {
|
|
|
- keyPressed = INPUT_KEY_PREV;
|
|
|
- } else {
|
|
|
- return MPRemoteCommandHandlerStatusCommandFailed;
|
|
|
- }
|
|
|
-
|
|
|
- emit input->receivedInput("AppleMediaKeys", keyPressed, InputBase::KeyPressed);
|
|
|
- return MPRemoteCommandHandlerStatusSuccess;
|
|
|
-}
|
|
|
-
|
|
|
--(MPRemoteCommandHandlerStatus)gotPlaybackPosition:(MPChangePlaybackPositionCommandEvent *)event
|
|
|
-{
|
|
|
- PlayerComponent::Get().seekTo(event.positionTime * 1000);
|
|
|
- return MPRemoteCommandHandlerStatusSuccess;
|
|
|
-}
|
|
|
-
|
|
|
-(void)mediaKeyTap:(SPMediaKeyTap *)keyTap receivedMediaKeyEvent:(NSEvent *)event
|
|
|
{
|
|
|
int keyCode = (([event data1] & 0xFFFF0000) >> 16);
|
|
@@ -98,7 +45,7 @@
|
|
|
|
|
|
switch (keyCode) {
|
|
|
case NX_KEYTYPE_PLAY:
|
|
|
- keyPressed = INPUT_KEY_PLAY_PAUSE;
|
|
|
+ keyPressed = INPUT_KEY_PLAY;
|
|
|
break;
|
|
|
case NX_KEYTYPE_FAST:
|
|
|
keyPressed = "KEY_FAST";
|
|
@@ -122,97 +69,9 @@
|
|
|
|
|
|
@end
|
|
|
|
|
|
-// macOS private enum
|
|
|
-enum {
|
|
|
- MRNowPlayingClientVisibilityUndefined = 0,
|
|
|
- MRNowPlayingClientVisibilityAlwaysVisible,
|
|
|
- MRNowPlayingClientVisibilityVisibleWhenBackgrounded,
|
|
|
- MRNowPlayingClientVisibilityNeverVisible
|
|
|
-};
|
|
|
-
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
bool InputAppleMediaKeys::initInput()
|
|
|
{
|
|
|
- m_currentTime = 0;
|
|
|
- m_pendingUpdate = false;
|
|
|
m_delegate = [[MediaKeysDelegate alloc] initWithInput:this];
|
|
|
- if (NSClassFromString(@"MPNowPlayingInfoCenter")) {
|
|
|
- connect(&PlayerComponent::Get(), &PlayerComponent::stateChanged, this, &InputAppleMediaKeys::handleStateChanged);
|
|
|
- connect(&PlayerComponent::Get(), &PlayerComponent::positionUpdate, this, &InputAppleMediaKeys::handlePositionUpdate);
|
|
|
- connect(&PlayerComponent::Get(), &PlayerComponent::updateDuration, this, &InputAppleMediaKeys::handleUpdateDuration);
|
|
|
- void* lib = dlopen("/System/Library/PrivateFrameworks/MediaRemote.framework/MediaRemote", RTLD_NOW);
|
|
|
- if (lib) {
|
|
|
-#define LOAD_FUNC(name) \
|
|
|
- name = (name ## Func)dlsym(lib, "MRMediaRemote" #name)
|
|
|
- LOAD_FUNC(SetNowPlayingVisibility);
|
|
|
- LOAD_FUNC(GetLocalOrigin);
|
|
|
- LOAD_FUNC(SetCanBeNowPlayingApplication);
|
|
|
- if (SetCanBeNowPlayingApplication)
|
|
|
- SetCanBeNowPlayingApplication(1);
|
|
|
- }
|
|
|
- }
|
|
|
return true;
|
|
|
}
|
|
|
-
|
|
|
-///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
-static MPNowPlayingPlaybackState convertState(PlayerComponent::State newState)
|
|
|
-{
|
|
|
- switch (newState) {
|
|
|
- case PlayerComponent::State::finished:
|
|
|
- return MPNowPlayingPlaybackStateStopped;
|
|
|
- case PlayerComponent::State::canceled:
|
|
|
- case PlayerComponent::State::error:
|
|
|
- return MPNowPlayingPlaybackStateInterrupted;
|
|
|
- case PlayerComponent::State::buffering:
|
|
|
- case PlayerComponent::State::paused:
|
|
|
- return MPNowPlayingPlaybackStatePaused;
|
|
|
- case PlayerComponent::State::playing:
|
|
|
- return MPNowPlayingPlaybackStatePlaying;
|
|
|
- default:
|
|
|
- return MPNowPlayingPlaybackStateUnknown;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
-void InputAppleMediaKeys::handleStateChanged(PlayerComponent::State newState, PlayerComponent::State oldState)
|
|
|
-{
|
|
|
- MPNowPlayingPlaybackState newMPState = convertState(newState);
|
|
|
- MPNowPlayingInfoCenter *center = [MPNowPlayingInfoCenter defaultCenter];
|
|
|
- NSMutableDictionary *playingInfo = [NSMutableDictionary dictionaryWithDictionary:center.nowPlayingInfo];
|
|
|
- [playingInfo setObject:[NSNumber numberWithDouble:(double)m_currentTime / 1000] forKey:MPNowPlayingInfoPropertyElapsedPlaybackTime];
|
|
|
- center.nowPlayingInfo = playingInfo;
|
|
|
- [MPNowPlayingInfoCenter defaultCenter].playbackState = newMPState;
|
|
|
- if (SetNowPlayingVisibility && GetLocalOrigin) {
|
|
|
- if (newState == PlayerComponent::State::finished || newState == PlayerComponent::State::canceled || newState == PlayerComponent::State::error)
|
|
|
- SetNowPlayingVisibility(GetLocalOrigin(), MRNowPlayingClientVisibilityNeverVisible);
|
|
|
- else if (newState == PlayerComponent::State::paused || newState == PlayerComponent::State::playing || newState == PlayerComponent::State::buffering)
|
|
|
- SetNowPlayingVisibility(GetLocalOrigin(), MRNowPlayingClientVisibilityAlwaysVisible);
|
|
|
- }
|
|
|
-
|
|
|
- m_pendingUpdate = true;
|
|
|
-}
|
|
|
-
|
|
|
-///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
-void InputAppleMediaKeys::handlePositionUpdate(quint64 position)
|
|
|
-{
|
|
|
- m_currentTime = position;
|
|
|
-
|
|
|
- if (m_pendingUpdate) {
|
|
|
- MPNowPlayingInfoCenter *center = [MPNowPlayingInfoCenter defaultCenter];
|
|
|
- NSMutableDictionary *playingInfo = [NSMutableDictionary dictionaryWithDictionary:center.nowPlayingInfo];
|
|
|
- [playingInfo setObject:[NSNumber numberWithDouble:(double)position / 1000] forKey:MPNowPlayingInfoPropertyElapsedPlaybackTime];
|
|
|
- center.nowPlayingInfo = playingInfo;
|
|
|
- [MPNowPlayingInfoCenter defaultCenter].playbackState = [MPNowPlayingInfoCenter defaultCenter].playbackState;
|
|
|
- m_pendingUpdate = false;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
-void InputAppleMediaKeys::handleUpdateDuration(qint64 duration)
|
|
|
-{
|
|
|
- MPNowPlayingInfoCenter *center = [MPNowPlayingInfoCenter defaultCenter];
|
|
|
- NSMutableDictionary *playingInfo = [NSMutableDictionary dictionaryWithDictionary:center.nowPlayingInfo];
|
|
|
- [playingInfo setObject:[NSNumber numberWithDouble:(double)duration / 1000] forKey:MPMediaItemPropertyPlaybackDuration];
|
|
|
- center.nowPlayingInfo = playingInfo;
|
|
|
- m_pendingUpdate = true;
|
|
|
-}
|