如何在Java中拦截音乐控制键盘快捷键?

11

如果您的键盘有播放/暂停等按钮(音乐控制快捷方式),并按下它们,则iTunes将打开(至少在Mac上)。

如果您最近打开了其他音乐播放器,如Spotify,则实际上会拦截快捷键,并且iTunes不会执行任何操作。

嗯,我想用Java制作一个音乐播放器,并且希望拥有相同的行为。我希望我的应用程序拦截这样的快捷方式,而其他程序不应该能够干扰。

我正在使用JavaFX,尽管我认为这并不重要。

我该如何实现?

我已经能够使用JNativeHook检测用户按下的键,但我不知道如何拦截这些键,使得其他应用程序无法对其进行操作。


它不支持Linux,但您可以在Windows和OS X上使用事件。请参阅:https://github.com/kwhat/jnativehook/wiki/ConsumingEvents - Alex Barker
2个回答

4
一旦检测到按键,您可以发送暂停键以暂停由iTunes播放的歌曲,您可以使用一个布尔变量来区分键盘上键入的快捷键和程序发送的快捷键(如果需要的话)。
或者
您可以使用一些C代码(在Java程序中启动C程序),请参阅@Dave Delongs的答案Modify NSEvent to send a different key than the one that was pressed。您可以设置不同的键盘快捷键,并修改C程序,以便在按下iTunes快捷键时发送您的快捷键,如果需要键码,请参见Where can I find a list of Mac virtual key codes? 例如,如果您的音乐程序使用p播放歌曲r听下一首歌曲,而iTunes使用空格键播放歌曲和右箭头键转到下一首歌曲,则可以修改@Dave Delongs的答案,以下是更改内容:
#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);
}

1
你可以使用iTunesPatch中的一些代码来实现你想要的功能,但似乎需要在安装时修改系统守护进程,并且可能需要使用Objective-C/Swift。
有关iTunesPatch的更多详细信息,请参阅此处的博客文章。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接