There was a great question on Stack Overflow today about how to catch media key events (such as play/pause or seek forward/backward) in your own app. I thought I’d post the solution I use in Transcriva.
My approach (which may not be the only or best approach) was to subclass NSApplication and catch calls to -sendEvent: (through which keyboard events, among other kinds, are sent). If the event is a media key press, I translate it to the appropriate action call to my app delegate.
The complete (relevant) code listing:
import (void)sendEvent:(NSEvent *)event { // Catch media key events if ([event type] == NSSystemDefined && [event subtype] == 8) { int keyCode = (([event data1] & 0xFFFF0000) >> 16); int keyFlags = ([event data1] & 0x0000FFFF); int keyState = (((keyFlags & 0xFF00) >> 8)) == 0xA; // Process the media key event and return [self mediaKeyEvent:keyCode state:keyState]; return; } // Continue on to super [super sendEvent:event]; } (void)mediaKeyEvent:(int)key state:(BOOL)state { switch (key) { // Play pressed case NX_KEYTYPE_PLAY: if (state == NO) [(TSAppController *)[self delegate] togglePlayPause:self]; break; // Rewind case NX_KEYTYPE_FAST: if (state == YES) [(TSAppController *)[self delegate] seekForward:self]; break; // Previous case NX_KEYTYPE_REWIND: if (state == YES) [(TSAppController *)[self delegate] seekBack:self]; break; } }

Just remember to set your app’s principal class to your new NSApplication subclass (see below) and implement the -togglePlayPause:, -seekForward:, and -seekBack: actions in your app delegate (and make sure you have an app delegate).