在Mac上模拟媒体键按下

问题描述 投票:5回答:3

有没有办法模仿普通Apple笔记本上的媒体键按键(音量增/减,播放,暂停,上一下,下一个)?

怎么样?

macos keyevent
3个回答
11
投票

这需要一些时间和许多黑客(尝试使用ctypes,IOKit本机接口,Quartz和/或Cocoa)。这似乎是一个简单的解决方案:

#!/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)

(虽然我现在在Python中需要这个,但我的问题并不是与Python有关,当然你可以轻松地将其翻译成任何其他语言,尤其是ObjC。)


5
投票

谢谢Albert,谢谢!我对你的脚本进行了一些扩展,使它成为一个可执行文件,然后可以由Quicksilver或另一个启动程序/触发器处理程序调用。

#!/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()

该脚本可以在https://gist.github.com/4078034找到


0
投票

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)
    }
© www.soinside.com 2019 - 2024. All rights reserved.