Implemented support for MediaPlayer framework, which fixes media key support on newer systems, and also media info reporting

CQTexperiment
Christopher Snowhill 2019-11-13 19:13:59 -08:00
parent 9d8551852b
commit 09777d4554
6 changed files with 127 additions and 7 deletions

View File

@ -92,9 +92,12 @@ OSStatus handleHotKey(EventHandlerCallRef nextHandler,EventRef theEvent,void *us
- (void)clickPlay; - (void)clickPlay;
- (void)clickPause;
- (void)clickStop;
- (void)clickPrev; - (void)clickPrev;
- (void)clickNext; - (void)clickNext;
- (void)clickSpam; - (void)clickSpam;
- (void)clickSeek: (NSTimeInterval)position;
- (IBAction)increaseFontSize:(id)sender; - (IBAction)increaseFontSize:(id)sender;
- (IBAction)decreaseFontSize:(id)sender; - (IBAction)decreaseFontSize:(id)sender;

View File

@ -521,6 +521,16 @@
[playbackController playPauseResume:self]; [playbackController playPauseResume:self];
} }
- (void)clickPause
{
[playbackController pause:self];
}
- (void)clickStop
{
[playbackController stop:self];
}
- (void)clickPrev - (void)clickPrev
{ {
[playbackController prev:nil]; [playbackController prev:nil];
@ -536,6 +546,11 @@
[playbackController spam]; [playbackController spam];
} }
- (void)clickSeek:(NSTimeInterval)position
{
[playbackController seek:self toTime:position];
}
- (void)changeFontSize:(float)size - (void)changeFontSize:(float)size
{ {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

View File

@ -11,6 +11,12 @@
#import "SPMediaKeyTap.h" #import "SPMediaKeyTap.h"
#import "Logging.h" #import "Logging.h"
#import <MediaPlayer/MPNowPlayingInfoCenter.h>
#import <MediaPlayer/MPRemoteCommandCenter.h>
#import <MediaPlayer/MPRemoteCommand.h>
#import <MediaPlayer/MPMediaItem.h>
#import <MediaPlayer/MPRemoteCommandEvent.h>
@implementation MediaKeysApplication @implementation MediaKeysApplication
+(void)initialize; +(void)initialize;
@ -31,6 +37,23 @@
options:NSKeyValueObservingOptionNew options:NSKeyValueObservingOptionNew
context:nil]; context:nil];
MPRemoteCommandCenter *remoteCommandCenter = [MPRemoteCommandCenter sharedCommandCenter];
if (remoteCommandCenter) {
[remoteCommandCenter.playCommand setEnabled:YES];
[remoteCommandCenter.pauseCommand setEnabled:YES];
[remoteCommandCenter.togglePlayPauseCommand setEnabled:YES];
[remoteCommandCenter.changePlaybackPositionCommand setEnabled:YES];
[remoteCommandCenter.nextTrackCommand setEnabled:YES];
[remoteCommandCenter.previousTrackCommand setEnabled:YES];
[[remoteCommandCenter playCommand] addTarget:[self delegate] action:@selector(clickPlay)];
[[remoteCommandCenter pauseCommand] addTarget:[self delegate] action:@selector(clickPause)];
[[remoteCommandCenter togglePlayPauseCommand] addTarget:[self delegate] action:@selector(clickPlay)];
[[remoteCommandCenter changePlaybackPositionCommand] addTarget:self action:@selector(clickSeek:)];
[[remoteCommandCenter nextTrackCommand] addTarget:[self delegate] action:@selector(clickNext)];
[[remoteCommandCenter previousTrackCommand] addTarget:[self delegate] action:@selector(clickPrev)];
} else {
keyTap = [[SPMediaKeyTap alloc] initWithDelegate:self]; keyTap = [[SPMediaKeyTap alloc] initWithDelegate:self];
if([SPMediaKeyTap usesGlobalMediaKeyTap]) { if([SPMediaKeyTap usesGlobalMediaKeyTap]) {
[keyTap startWatchingMediaKeys]; [keyTap startWatchingMediaKeys];
@ -38,6 +61,11 @@
else else
ALog(@"Media key monitoring disabled"); ALog(@"Media key monitoring disabled");
} }
}
- (void)clickSeek: (MPChangePlaybackPositionCommandEvent*)event {
[(AppController *)[self delegate] clickSeek:event.positionTime];
}
- (void)sendEvent: (NSEvent*)event - (void)sendEvent: (NSEvent*)event
{ {

View File

@ -59,6 +59,7 @@ extern NSDictionary * makeRGInfo(PlaylistEntry *pe);
- (IBAction)next:(id)sender; - (IBAction)next:(id)sender;
- (IBAction)prev:(id)sender; - (IBAction)prev:(id)sender;
- (IBAction)seek:(id)sender; - (IBAction)seek:(id)sender;
- (IBAction)seek:(id)sender toTime:(NSTimeInterval)time;
- (IBAction)eventSeekForward:(id)sender; - (IBAction)eventSeekForward:(id)sender;
- (void)seekForward:(double)sender; - (void)seekForward:(double)sender;
- (IBAction)eventSeekBackward:(id)sender; - (IBAction)eventSeekBackward:(id)sender;
@ -67,6 +68,8 @@ extern NSDictionary * makeRGInfo(PlaylistEntry *pe);
- (IBAction)spam; - (IBAction)spam;
- (void)sendMetaData;
- (void)initDefaults; - (void)initDefaults;
- (void)audioFadeDown:(NSTimer *)audioTimer; - (void)audioFadeDown:(NSTimer *)audioTimer;
- (void)audioFadeUp:(NSTimer *)audioTimer; - (void)audioFadeUp:(NSTimer *)audioTimer;

View File

@ -8,6 +8,12 @@
#import "PlaylistEntry.h" #import "PlaylistEntry.h"
#import "PlaylistLoader.h" #import "PlaylistLoader.h"
#import <MediaPlayer/MPNowPlayingInfoCenter.h>
#import <MediaPlayer/MPRemoteCommandCenter.h>
#import <MediaPlayer/MPRemoteCommand.h>
#import <MediaPlayer/MPMediaItem.h>
#import <MediaPlayer/MPRemoteCommandEvent.h>
#import "Logging.h" #import "Logging.h"
@implementation PlaybackController @implementation PlaybackController
@ -75,6 +81,8 @@ NSString *CogPlaybackDidStopNotficiation = @"CogPlaybackDidStopNotficiation";
{ {
[self pauseResume:self]; [self pauseResume:self];
} }
[self sendMetaData];
} }
- (IBAction)pauseResume:(id)sender - (IBAction)pauseResume:(id)sender
@ -89,6 +97,8 @@ NSString *CogPlaybackDidStopNotficiation = @"CogPlaybackDidStopNotficiation";
{ {
[audioPlayer pause]; [audioPlayer pause];
[self setPlaybackStatus: kCogStatusPaused]; [self setPlaybackStatus: kCogStatusPaused];
[self sendMetaData];
} }
- (IBAction)resume:(id)sender - (IBAction)resume:(id)sender
@ -100,6 +110,8 @@ NSString *CogPlaybackDidStopNotficiation = @"CogPlaybackDidStopNotficiation";
- (IBAction)stop:(id)sender - (IBAction)stop:(id)sender
{ {
[audioPlayer stop]; [audioPlayer stop];
[self sendMetaData];
} }
//called by double-clicking on table //called by double-clicking on table
@ -178,6 +190,8 @@ NSDictionary * makeRGInfo(PlaylistEntry *pe)
} }
#endif #endif
[self sendMetaData];
[audioPlayer play:[pe URL] withUserInfo:pe withRGInfo:makeRGInfo(pe) startPaused:paused]; [audioPlayer play:[pe URL] withUserInfo:pe withRGInfo:makeRGInfo(pe) startPaused:paused];
} }
@ -204,6 +218,8 @@ NSDictionary * makeRGInfo(PlaylistEntry *pe)
[self setPosition:pos]; [self setPosition:pos];
[[playlistController currentEntry] setCurrentPosition:pos]; [[playlistController currentEntry] setCurrentPosition:pos];
[self sendMetaData];
} }
- (IBAction)seek:(id)sender - (IBAction)seek:(id)sender
@ -212,6 +228,19 @@ NSDictionary * makeRGInfo(PlaylistEntry *pe)
[audioPlayer seekToTime:time]; [audioPlayer seekToTime:time];
[self setPosition:time];
[[playlistController currentEntry] setCurrentPosition:time];
[self sendMetaData];
}
- (IBAction)seek:(id)sender toTime:(NSTimeInterval)position
{
double time = (double)(position);
[audioPlayer seekToTime:time];
[self setPosition:time]; [self setPosition:time];
[[playlistController currentEntry] setCurrentPosition:time]; [[playlistController currentEntry] setCurrentPosition:time];
@ -244,6 +273,8 @@ NSDictionary * makeRGInfo(PlaylistEntry *pe)
[audioPlayer seekToTime:seekTo]; [audioPlayer seekToTime:seekTo];
[self setPosition:seekTo]; [self setPosition:seekTo];
} }
[self sendMetaData];
} }
- (IBAction)eventSeekBackward:(id)sender - (IBAction)eventSeekBackward:(id)sender
@ -260,6 +291,8 @@ NSDictionary * makeRGInfo(PlaylistEntry *pe)
[audioPlayer seekToTime:seekTo]; [audioPlayer seekToTime:seekTo];
[self setPosition:seekTo]; [self setPosition:seekTo];
[self sendMetaData];
} }
/* /*
@ -588,5 +621,38 @@ NSDictionary * makeRGInfo(PlaylistEntry *pe)
return seekable && [[playlistController currentEntry] seekable]; return seekable && [[playlistController currentEntry] seekable];
} }
- (void)sendMetaData {
MPNowPlayingInfoCenter * defaultCenter = [MPNowPlayingInfoCenter defaultCenter];
if (defaultCenter) {
PlaylistEntry * entry = [playlistController currentEntry];
NSMutableDictionary *songInfo = [[NSMutableDictionary alloc] init];
if (entry) {
if ([entry title])
[songInfo setObject:[entry title] forKey:MPMediaItemPropertyTitle];
if ([entry artist])
[songInfo setObject:[entry artist] forKey:MPMediaItemPropertyArtist];
if ([entry album])
[songInfo setObject:[entry album] forKey:MPMediaItemPropertyAlbumTitle];
[songInfo setObject:[NSNumber numberWithFloat:[entry currentPosition]] forKey:MPNowPlayingInfoPropertyElapsedPlaybackTime];
[songInfo setObject:[entry length] forKey:MPMediaItemPropertyPlaybackDuration];
[songInfo setObject:[NSNumber numberWithFloat:[entry index]] forKey:MPMediaItemPropertyPersistentID];
}
if (playbackStatus == kCogStatusPlaying) {
[MPNowPlayingInfoCenter defaultCenter].playbackState = MPNowPlayingPlaybackStatePlaying;
} else if (playbackStatus == kCogStatusPaused) {
[MPNowPlayingInfoCenter defaultCenter].playbackState = MPNowPlayingPlaybackStatePaused;
} else {
[MPNowPlayingInfoCenter defaultCenter].playbackState = MPNowPlayingPlaybackStateStopped;
}
[[MPNowPlayingInfoCenter defaultCenter] setNowPlayingInfo:songInfo];
}
}
@end @end

View File

@ -174,6 +174,7 @@
838491881808593200E7332D /* NDHotKey.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8384917E1808585D00E7332D /* NDHotKey.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; 838491881808593200E7332D /* NDHotKey.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8384917E1808585D00E7332D /* NDHotKey.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
8399D4E21805A55000B503B1 /* XmlContainer.m in Sources */ = {isa = PBXBuildFile; fileRef = 8399D4E01805A55000B503B1 /* XmlContainer.m */; }; 8399D4E21805A55000B503B1 /* XmlContainer.m in Sources */ = {isa = PBXBuildFile; fileRef = 8399D4E01805A55000B503B1 /* XmlContainer.m */; };
83A360B220E4E81D00192DAB /* Flac.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8303A30C20E4E3D000951EF8 /* Flac.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 83A360B220E4E81D00192DAB /* Flac.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8303A30C20E4E3D000951EF8 /* Flac.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
83AB903E237CEFD300A433D5 /* MediaPlayer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 83AB9031237CEFD300A433D5 /* MediaPlayer.framework */; };
83B06704180D579E008E3612 /* MIDI.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83B066A1180D5669008E3612 /* MIDI.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; 83B06704180D579E008E3612 /* MIDI.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83B066A1180D5669008E3612 /* MIDI.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
83BC5AB220E4C87100631CD4 /* DualWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 83BC5AB020E4C87100631CD4 /* DualWindow.m */; }; 83BC5AB220E4C87100631CD4 /* DualWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 83BC5AB020E4C87100631CD4 /* DualWindow.m */; };
83BC5ABF20E4CE7A00631CD4 /* InfoInspector.xib in Resources */ = {isa = PBXBuildFile; fileRef = 17D1B0D00F6320EA00694C57 /* InfoInspector.xib */; }; 83BC5ABF20E4CE7A00631CD4 /* InfoInspector.xib in Resources */ = {isa = PBXBuildFile; fileRef = 17D1B0D00F6320EA00694C57 /* InfoInspector.xib */; };
@ -1006,6 +1007,7 @@
83859520234FEB35004E9946 /* Cog.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Cog.entitlements; sourceTree = "<group>"; }; 83859520234FEB35004E9946 /* Cog.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Cog.entitlements; sourceTree = "<group>"; };
8399D4E01805A55000B503B1 /* XmlContainer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XmlContainer.m; sourceTree = "<group>"; }; 8399D4E01805A55000B503B1 /* XmlContainer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XmlContainer.m; sourceTree = "<group>"; };
8399D4E11805A55000B503B1 /* XmlContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XmlContainer.h; sourceTree = "<group>"; }; 8399D4E11805A55000B503B1 /* XmlContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XmlContainer.h; sourceTree = "<group>"; };
83AB9031237CEFD300A433D5 /* MediaPlayer.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MediaPlayer.framework; path = System/Library/Frameworks/MediaPlayer.framework; sourceTree = SDKROOT; };
83B0669C180D5668008E3612 /* MIDI.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = MIDI.xcodeproj; path = Plugins/MIDI/MIDI.xcodeproj; sourceTree = "<group>"; }; 83B0669C180D5668008E3612 /* MIDI.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = MIDI.xcodeproj; path = Plugins/MIDI/MIDI.xcodeproj; sourceTree = "<group>"; };
83BC5AB020E4C87100631CD4 /* DualWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DualWindow.m; path = Window/DualWindow.m; sourceTree = "<group>"; }; 83BC5AB020E4C87100631CD4 /* DualWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DualWindow.m; path = Window/DualWindow.m; sourceTree = "<group>"; };
83BC5AB120E4C87100631CD4 /* DualWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DualWindow.h; path = Window/DualWindow.h; sourceTree = "<group>"; }; 83BC5AB120E4C87100631CD4 /* DualWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DualWindow.h; path = Window/DualWindow.h; sourceTree = "<group>"; };
@ -1069,6 +1071,7 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
83AB903E237CEFD300A433D5 /* MediaPlayer.framework in Frameworks */,
83E6B7651816178200D4576D /* Sparkle.framework in Frameworks */, 83E6B7651816178200D4576D /* Sparkle.framework in Frameworks */,
838491871808591F00E7332D /* NDHotKey.framework in Frameworks */, 838491871808591F00E7332D /* NDHotKey.framework in Frameworks */,
8355D6B8180613FB00D05687 /* Security.framework in Frameworks */, 8355D6B8180613FB00D05687 /* Security.framework in Frameworks */,
@ -1558,6 +1561,7 @@
29B97323FDCFA39411CA2CEA /* Frameworks */ = { 29B97323FDCFA39411CA2CEA /* Frameworks */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
83AB9031237CEFD300A433D5 /* MediaPlayer.framework */,
8355D6B7180613FB00D05687 /* Security.framework */, 8355D6B7180613FB00D05687 /* Security.framework */,
1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */, 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */,
1058C7A2FEA54F0111CA2CBB /* Other Frameworks */, 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */,
@ -1959,6 +1963,7 @@
LastUpgradeCheck = 1100; LastUpgradeCheck = 1100;
TargetAttributes = { TargetAttributes = {
8D1107260486CEB800E47090 = { 8D1107260486CEB800E47090 = {
DevelopmentTeam = 4S876G9VCD;
ProvisioningStyle = Automatic; ProvisioningStyle = Automatic;
}; };
}; };