emulate media key press on Mac

前端 未结 3 1453
挽巷
挽巷 2020-12-16 05:41

Is there a way to emulate key presses of the media keys (volume up/down, play, pause, prev, next) on common Apple notebooks?

How?

相关标签:
3条回答
  • 2020-12-16 05:53

    Thank you Albert for that! I expanded on your script a bit to make it an executable that could in turn be called by Quicksilver or another launcher/trigger handler.

    #!/usr/bin/python
    
    # CLI program to control the mediakeys on OS X. Used to emulate the mediakey on a keyboard with no such keys.
    # Easiest used in combination with a launcher/trigger software such as Quicksilver.
    # Main part taken from http://stackoverflow.com/questions/11045814/emulate-media-key-press-on-mac
    # Glue to make it into cli program by Fredrik Wallner http://www.wallner.nu/fredrik/
    
    import Quartz
    import sys
    
    # NSEvent.h
    NSSystemDefined = 14
    
    # hidsystem/ev_keymap.h
    NX_KEYTYPE_SOUND_UP = 0
    NX_KEYTYPE_SOUND_DOWN = 1
    NX_KEYTYPE_PLAY = 16
    NX_KEYTYPE_NEXT = 17
    NX_KEYTYPE_PREVIOUS = 18
    NX_KEYTYPE_FAST = 19
    NX_KEYTYPE_REWIND = 20
    
    supportedcmds = {'playpause': NX_KEYTYPE_PLAY, 'next': NX_KEYTYPE_NEXT, 'prev': NX_KEYTYPE_PREVIOUS, 'volup': NX_KEYTYPE_SOUND_UP, 'voldown': NX_KEYTYPE_SOUND_DOWN}
    
    def HIDPostAuxKey(key):
        def doKey(down):
            ev = Quartz.NSEvent.otherEventWithType_location_modifierFlags_timestamp_windowNumber_context_subtype_data1_data2_(
                NSSystemDefined, # type
                (0,0), # location
                0xa00 if down else 0xb00, # flags
                0, # timestamp
                0, # window
                0, # ctx
                8, # subtype
                (key << 16) | ((0xa if down else 0xb) << 8), # data1
                -1 # data2
                )
            cev = ev.CGEvent()
            Quartz.CGEventPost(0, cev)
        doKey(True)
        doKey(False)
    
    if __name__ == "__main__":
        try:
            command = sys.argv[1]
            assert(command in supportedcmds)
            HIDPostAuxKey(supportedcmds[command])
        except (IndexError, AssertionError):
            print "Usage: %s command" % (sys.argv[0],)
            print "\tSupported commands are %s" % supportedcmds.keys()
    

    The script can be found at https://gist.github.com/4078034

    0 讨论(0)
  • 2020-12-16 06:15

    That took some time and many hacks (trying around with ctypes, the IOKit native interface, Quartz and/or Cocoa). This seems like an easy solution now:

    #!/usr/bin/python
    
    import Quartz
    
    # NSEvent.h
    NSSystemDefined = 14
    
    # hidsystem/ev_keymap.h
    NX_KEYTYPE_SOUND_UP = 0
    NX_KEYTYPE_SOUND_DOWN = 1
    NX_KEYTYPE_PLAY = 16
    NX_KEYTYPE_NEXT = 17
    NX_KEYTYPE_PREVIOUS = 18
    NX_KEYTYPE_FAST = 19
    NX_KEYTYPE_REWIND = 20
    
    def HIDPostAuxKey(key):
        def doKey(down):
            ev = Quartz.NSEvent.otherEventWithType_location_modifierFlags_timestamp_windowNumber_context_subtype_data1_data2_(
                NSSystemDefined, # type
                (0,0), # location
                0xa00 if down else 0xb00, # flags
                0, # timestamp
                0, # window
                0, # ctx
                8, # subtype
                (key << 16) | ((0xa if down else 0xb) << 8), # data1
                -1 # data2
                )
            cev = ev.CGEvent()
            Quartz.CGEventPost(0, cev)
        doKey(True)
        doKey(False)
    
    for _ in range(10):
        HIDPostAuxKey(NX_KEYTYPE_SOUND_UP)
    HIDPostAuxKey(NX_KEYTYPE_PLAY)
    

    (While I needed this in Python for now, my question was not really Python related and of course you can easily translate that to any other language, esp. ObjC.)

    0 讨论(0)
  • 2020-12-16 06:15

    Swift 5 / MacOS 10.14.4 / Xcode 10.2

        @IBAction func mediaPressed(_ sender: AnyObject) {
            let NX_KEYTYPE_SOUND_UP: UInt32 = 0
            let NX_KEYTYPE_SOUND_DOWN: UInt32 = 1
            let NX_KEYTYPE_PLAY: UInt32 = 16
            let NX_KEYTYPE_NEXT: UInt32 = 17
            let NX_KEYTYPE_PREVIOUS: UInt32 = 18
            let NX_KEYTYPE_FAST: UInt32 = 19
            let NX_KEYTYPE_REWIND: UInt32 = 20
    
            func HIDPostAuxKey(key: UInt32) {
                func doKey(down: Bool) {
                    let flags = NSEvent.ModifierFlags(rawValue: (down ? 0xa00 : 0xb00))
                    let data1 = Int((key<<16) | (down ? 0xa00 : 0xb00))
    
                    let ev = NSEvent.otherEvent(with: NSEvent.EventType.systemDefined,
                                                location: NSPoint(x:0,y:0),
                                                modifierFlags: flags,
                                                timestamp: 0,
                                                windowNumber: 0,
                                                context: nil,
                                                subtype: 8,
                                                data1: data1,
                                                data2: -1
                                                )
                    let cev = ev?.cgEvent
                    cev?.post(tap: CGEventTapLocation.cghidEventTap)
                }
                doKey(down: true)
                doKey(down: false)
            }
    
            for _ in 1...10 {
                HIDPostAuxKey(key:NX_KEYTYPE_SOUND_UP)
            }
            HIDPostAuxKey(key:NX_KEYTYPE_PLAY)
        }
    
    0 讨论(0)
提交回复
热议问题