Browse Source

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

master
Christopher Snowhill 4 months ago
parent
commit
09777d4554
6 changed files with 127 additions and 7 deletions
  1. +3
    -0
      Application/AppController.h
  2. +15
    -0
      Application/AppController.m
  3. +35
    -7
      Application/MediaKeysApplication.m
  4. +3
    -0
      Application/PlaybackController.h
  5. +66
    -0
      Application/PlaybackController.m
  6. +5
    -0
      Cog.xcodeproj/project.pbxproj

+ 3
- 0
Application/AppController.h View File

@@ -92,9 +92,12 @@ OSStatus handleHotKey(EventHandlerCallRef nextHandler,EventRef theEvent,void *us


- (void)clickPlay;
- (void)clickPause;
- (void)clickStop;
- (void)clickPrev;
- (void)clickNext;
- (void)clickSpam;
- (void)clickSeek: (NSTimeInterval)position;

- (IBAction)increaseFontSize:(id)sender;
- (IBAction)decreaseFontSize:(id)sender;


+ 15
- 0
Application/AppController.m View File

@@ -521,6 +521,16 @@
[playbackController playPauseResume:self];
}

- (void)clickPause
{
[playbackController pause:self];
}

- (void)clickStop
{
[playbackController stop:self];
}

- (void)clickPrev
{
[playbackController prev:nil];
@@ -536,6 +546,11 @@
[playbackController spam];
}

- (void)clickSeek:(NSTimeInterval)position
{
[playbackController seek:self toTime:position];
}

- (void)changeFontSize:(float)size
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];


+ 35
- 7
Application/MediaKeysApplication.m View File

@@ -11,6 +11,12 @@
#import "SPMediaKeyTap.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

+(void)initialize;
@@ -25,18 +31,40 @@

- (void)finishLaunching {
[super finishLaunching];
[[NSUserDefaults standardUserDefaults] addObserver:self
forKeyPath:@"allowLastfmMediaKeys"
options:NSKeyValueObservingOptionNew
context:nil];

keyTap = [[SPMediaKeyTap alloc] initWithDelegate:self];
if([SPMediaKeyTap usesGlobalMediaKeyTap]) {
[keyTap startWatchingMediaKeys];
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];
if([SPMediaKeyTap usesGlobalMediaKeyTap]) {
[keyTap startWatchingMediaKeys];
}
else
ALog(@"Media key monitoring disabled");
}
else
ALog(@"Media key monitoring disabled");
}

- (void)clickSeek: (MPChangePlaybackPositionCommandEvent*)event {
[(AppController *)[self delegate] clickSeek:event.positionTime];
}

- (void)sendEvent: (NSEvent*)event


+ 3
- 0
Application/PlaybackController.h View File

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

- (IBAction)spam;

- (void)sendMetaData;

- (void)initDefaults;
- (void)audioFadeDown:(NSTimer *)audioTimer;
- (void)audioFadeUp:(NSTimer *)audioTimer;


+ 66
- 0
Application/PlaybackController.m View File

@@ -8,6 +8,12 @@
#import "PlaylistEntry.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"

@implementation PlaybackController
@@ -75,6 +81,8 @@ NSString *CogPlaybackDidStopNotficiation = @"CogPlaybackDidStopNotficiation";
{
[self pauseResume:self];
}
[self sendMetaData];
}

- (IBAction)pauseResume:(id)sender
@@ -89,6 +97,8 @@ NSString *CogPlaybackDidStopNotficiation = @"CogPlaybackDidStopNotficiation";
{
[audioPlayer pause];
[self setPlaybackStatus: kCogStatusPaused];
[self sendMetaData];
}

- (IBAction)resume:(id)sender
@@ -100,6 +110,8 @@ NSString *CogPlaybackDidStopNotficiation = @"CogPlaybackDidStopNotficiation";
- (IBAction)stop:(id)sender
{
[audioPlayer stop];

[self sendMetaData];
}

//called by double-clicking on table
@@ -177,6 +189,8 @@ NSDictionary * makeRGInfo(PlaylistEntry *pe)
[playlistLoader performSelectorInBackground:@selector(loadInfoForEntries:) withObject:entries];
}
#endif
[self sendMetaData];
[audioPlayer play:[pe URL] withUserInfo:pe withRGInfo:makeRGInfo(pe) startPaused:paused];
}
@@ -204,6 +218,8 @@ NSDictionary * makeRGInfo(PlaylistEntry *pe)
[self setPosition:pos];
[[playlistController currentEntry] setCurrentPosition:pos];
[self sendMetaData];
}

- (IBAction)seek:(id)sender
@@ -215,6 +231,19 @@ NSDictionary * makeRGInfo(PlaylistEntry *pe)
[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];
[[playlistController currentEntry] setCurrentPosition:time];
}

- (IBAction)spam
@@ -244,6 +273,8 @@ NSDictionary * makeRGInfo(PlaylistEntry *pe)
[audioPlayer seekToTime:seekTo];
[self setPosition:seekTo];
}
[self sendMetaData];
}

- (IBAction)eventSeekBackward:(id)sender
@@ -260,6 +291,8 @@ NSDictionary * makeRGInfo(PlaylistEntry *pe)

[audioPlayer seekToTime:seekTo];
[self setPosition:seekTo];
[self sendMetaData];
}

/*
@@ -588,5 +621,38 @@ NSDictionary * makeRGInfo(PlaylistEntry *pe)
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

+ 5
- 0
Cog.xcodeproj/project.pbxproj View File

@@ -174,6 +174,7 @@
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 */; };
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, ); }; };
83BC5AB220E4C87100631CD4 /* DualWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 83BC5AB020E4C87100631CD4 /* DualWindow.m */; };
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>"; };
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>"; };
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>"; };
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>"; };
@@ -1069,6 +1071,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
83AB903E237CEFD300A433D5 /* MediaPlayer.framework in Frameworks */,
83E6B7651816178200D4576D /* Sparkle.framework in Frameworks */,
838491871808591F00E7332D /* NDHotKey.framework in Frameworks */,
8355D6B8180613FB00D05687 /* Security.framework in Frameworks */,
@@ -1558,6 +1561,7 @@
29B97323FDCFA39411CA2CEA /* Frameworks */ = {
isa = PBXGroup;
children = (
83AB9031237CEFD300A433D5 /* MediaPlayer.framework */,
8355D6B7180613FB00D05687 /* Security.framework */,
1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */,
1058C7A2FEA54F0111CA2CBB /* Other Frameworks */,
@@ -1959,6 +1963,7 @@
LastUpgradeCheck = 1100;
TargetAttributes = {
8D1107260486CEB800E47090 = {
DevelopmentTeam = 4S876G9VCD;
ProvisioningStyle = Automatic;
};
};


Loading…
Cancel
Save