Thursday, April 28, 2016

How to intercept music control keyboard shortcuts in Java?

Leave a Comment

If your keyboard has buttons for play/pause/etc (music control shortcuts), and you press them, iTunes will open (at least on Mac).

If you recently opened another music player, like Spotify, it will actually intercept the shortcut keys, and iTunes won't do anything.

Well, I want to make a music player with Java, and I want to have the same behavior. I want my application to intercept such shortcuts, and other programs shouldn't be able to interfere.

I am using JavaFX, although I don't think that really matters.

How can I achieve this?

I am already able to detect they keys the user presses using JNativeHook, but I do not know how to intercept the keys so that other applications won't do things with them.

2 Answers

Answers 1

Once you detect the keys, you could send the pause key so that the song that is being played by itunes is paused, you could use a boolean variable to detect between the shortcuts being typed on the keyboard or being send by the program(in case if you need)

or

You could use some c code(start the c program along with your java program) take a look at @Dave Delongs answer over here Modify NSEvent to send a different key than the one that was pressed You could have a different keyboard shortcut and modify the c program to send your shortcut keys while the Itunes Shortcut keys are pressed, if you need the key codes Where can I find a list of Mac virtual key codes?

for example if your music program uses p to play songs and r to listen to the next song, and itunes uses spacebar to play songs and right arrow key to go to the next one, you could do modify @Dave Delongs answer here are the changes :-

#import <Cocoa/Cocoa.h>  CGEventRef myCGEventCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon) {  //0x31 is the virtual keycode for "Spacebar" //0x23 is the virtual keycode for "p"   if (CGEventGetIntegerValueField(event, kCGKeyboardEventKeycode) == 0x31) {     CGEventSetIntegerValueField(event, kCGKeyboardEventKeycode, 0x23);   }  //0x7C is the virtual keycode for "Right arrow" //0x0F is the virtual keycode for "R"   if (CGEventGetIntegerValueField(event, kCGKeyboardEventKeycode) == 0x7C) {     CGEventSetIntegerValueField(event, kCGKeyboardEventKeycode, 0x0F);   }    return event; }  int main(int argc, char *argv[]) {   NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];   CFRunLoopSourceRef runLoopSource;    CFMachPortRef eventTap = CGEventTapCreate(kCGHIDEventTap, kCGHeadInsertEventTap, kCGEventTapOptionDefault, kCGEventMaskForAllEvents, myCGEventCallback, NULL);    if (!eventTap) {     NSLog(@"Couldn't create event tap!");     exit(1);   }    runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0);    CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes);    CGEventTapEnable(eventTap, true);    CFRunLoopRun();    CFRelease(eventTap);   CFRelease(runLoopSource);   [pool release];    exit(0); } 

Answers 2

You may be able to use some of the code from iTunesPatch to accomplish what you're looking for, but it appears that a system daemon may need to be modified upon installation, and you will likely have to use Objective-C/Swift.

There are further details about iTunesPatch in a blog post here.

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment