Skip to content

Instantly share code, notes, and snippets.

@dnicolson
Created December 24, 2019 18:16
Show Gist options
  • Save dnicolson/f97b8d80fe03e433d58a9f82e30a9431 to your computer and use it in GitHub Desktop.
Save dnicolson/f97b8d80fe03e433d58a9f82e30a9431 to your computer and use it in GitHub Desktop.
Use the MediaRemote private framework to get and set the playing state of the Touch Bar based on media change events
// clang -x objective-c -framework Foundation -framework MediaRemote -F /System/Library/PrivateFrameworks TouchBarMediaKeys.m -o TouchBarMediaKeys
// ./TouchBarMediaKeys
#import <Foundation/Foundation.h>
#import <MediaPlayer/MediaPlayer.h>
enum {
kMRPlaybackStateUnknown = 0,
kMRPlaybackStatePlaying,
kMRPlaybackStatePaused,
kMRPlaybackStateStopped,
kMRPlaybackStateInterrupted
};
typedef uint32_t MRPlaybackState;
typedef void (^MRMediaRemoteGetNowPlayingApplicationIsPlayingBlock)(BOOL);
typedef struct _MROrigin *MROriginRef;
typedef uint32_t MRMediaRemoteError;
typedef void (^MRMediaRemoteGetNowPlayingApplicationPlaybackStateCompletion)(MRPlaybackState playbackState);
void MRMediaRemoteSetNowPlayingApplicationOverrideEnabled(BOOL);
void MRMediaRemoteRegisterForNowPlayingNotifications(dispatch_queue_t);
BOOL MRMediaRemoteSetCanBeNowPlayingApplication(BOOL);
MROriginRef MRMediaRemoteGetLocalOrigin(void);
void MRMediaRemoteGetNowPlayingApplicationPlaybackState(dispatch_queue_t, MRMediaRemoteGetNowPlayingApplicationPlaybackStateCompletion);
void MRMediaRemoteSetNowPlayingApplicationPlaybackStateForOrigin(MROriginRef, MRPlaybackState, dispatch_queue_t, void(^completion)(MRMediaRemoteError));
extern NSString *kMRMediaRemoteNowPlayingApplicationIsPlayingDidChangeNotification;
@interface TouchBarMediaKeys : NSObject
- (void)nowPlayingChange:(NSNotification *)notification;
@end
@implementation TouchBarMediaKeys
- (void)nowPlayingChange:(NSNotification *)notification {
MRMediaRemoteGetNowPlayingApplicationPlaybackState(dispatch_get_main_queue(), ^(MRPlaybackState playbackState) {
NSLog(@"kMRPlaybackStateUnknown: %d", playbackState == kMRPlaybackStateUnknown);
NSLog(@"kMRPlaybackStatePlaying: %d", playbackState == kMRPlaybackStatePlaying);
NSLog(@"kMRPlaybackStateStopped: %d", playbackState == kMRPlaybackStateStopped);
NSLog(@"kMRPlaybackStatePaused: %d", playbackState == kMRPlaybackStatePaused);
NSLog(@"kMRPlaybackStateInterrupted: %d", playbackState == kMRPlaybackStateInterrupted);
});
// Set playback state to playing
// MRMediaRemoteSetNowPlayingApplicationPlaybackStateForOrigin(MRMediaRemoteGetLocalOrigin(), kMRPlaybackStatePlaying, dispatch_get_main_queue(), ^(MRMediaRemoteError error) {});
// Set playback state to stopped
// MRMediaRemoteSetNowPlayingApplicationPlaybackStateForOrigin(MRMediaRemoteGetLocalOrigin(), kMRPlaybackStateStopped, dispatch_get_main_queue(), ^(MRMediaRemoteError error) {});
}
@end
int main(int argc, const char *argv[]) {
@autoreleasepool {
TouchBarMediaKeys *touchBarMediaKeys = [[TouchBarMediaKeys alloc] init];
[[NSNotificationCenter defaultCenter]
addObserver:touchBarMediaKeys
selector:@selector(nowPlayingChange:)
name:kMRMediaRemoteNowPlayingApplicationIsPlayingDidChangeNotification
object:nil];
MRMediaRemoteRegisterForNowPlayingNotifications(dispatch_get_main_queue());
MRMediaRemoteSetCanBeNowPlayingApplication(YES);
[[NSRunLoop currentRunLoop] run];
}
return 0;
}
@varenc
Copy link

varenc commented Apr 8, 2020

This rocks! thank you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment