Skip to content

Instantly share code, notes, and snippets.

@varenc
Forked from dnicolson/MediaRemoteEvents.m
Last active April 21, 2022 18:31
Show Gist options
  • Save varenc/98858e5f042a578b6fc8c4ff24178347 to your computer and use it in GitHub Desktop.
Save varenc/98858e5f042a578b6fc8c4ff24178347 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
// varenc's very simple fork of dnicolson's gist.
//
// changelog: on start immediately output the current MediaRemote state
// todo: might turn this into a command line util for personal workflow automation.
//
// clang -x objective-c -framework Foundation -framework MediaRemote -F /System/Library/PrivateFrameworks MediaRemoteEvents.m -o MediaRemoteEvents.m
// ./MediaRemoteEvents.m
#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);
// post notification immediately to output the current state!
[[NSNotificationCenter defaultCenter] postNotificationName:kMRMediaRemoteNowPlayingApplicationIsPlayingDidChangeNotification object:nil];
[[NSRunLoop currentRunLoop] run];
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment