[macApp] Macでメディアキーの押下をエミュレートする

# メディアキーとは

ここでメディアキーと呼んでいるのは、キーボードの最上段にある↓このキーのことです。
![mediaKey.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283293/6b4ac054-ba65-7301-4c6e-9a47f9c0c674.png)

メディアキーをプログラムから入力するコードは以下の通り。

# メディアキー入力

```swift
func HIDPostMediaKey(_ key: Int32) {
    func doMediaKey(_ key: Int, down: Bool) {
        let modifierFlags = NSEvent.ModifierFlags(rawValue: down ? 0xA00 : 0xB00)
        let nsEvent = NSEvent.otherEvent(with: .systemDefined, location: NSPoint(x: 0, y: 0), modifierFlags: modifierFlags, timestamp: 0, windowNumber: 0, context: nil, subtype: 8, data1: (key << 16) | ((down ? 0xA : 0xB) << 8), data2: -1)
        let cgEvent = nsEvent?.cgEvent
        cgEvent?.post(tap: .cghidEventTap)
    }
    doMediaKey(Int(key), down: true)  //key press
    doMediaKey(Int(key), down: false) //key release
}
```

<br>

使い方は簡単で、引数に**キータイプ**を指定するだけ。例えば、音量アップなら`NX_KEYTYPE_SOUND_UP`を指定する。

```swift:音量アップ
  HIDPostMediaKey(NX_KEYTYPE_SOUND_UP)
```

<br>

引数で指定する**キータイプ**は、下記の通り。

|キー|キータイプ定数|
|:-:|:-|
|![f1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283293/79ec7286-d8e1-5838-04a3-864c5b4d74f4.png)|NX_KEYTYPE_BRIGHTNESS_DOWN|
|![f2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283293/26d586c8-47b2-64a2-1c23-1c1c72a0f8da.png)|NX_KEYTYPE_BRIGHTNESS_UP|
|![f7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283293/2a5f4fa8-153e-906f-f342-65574bcf0d7d.png)|NX_KEYTYPE_REWIND|
|![f8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283293/b21f7b58-b4b6-de9b-c782-8468c9efcfbe.png)|NX_KEYTYPE_PLAY|
|![f9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283293/7625305c-8e46-4abc-d2c0-9c30a73d5f68.png)|NX_KEYTYPE_FAST|
|![f10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283293/9538b5de-d06d-8507-2e03-d6ae1f6845f5.png)|NX_KEYTYPE_MUTE|
|![f11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283293/94f94df7-0fde-8e7a-4f9b-f85465daf4a9.png)|NX_KEYTYPE_SOUND_DOWN|
|![f12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283293/21078bb3-1e6a-3704-5d69-02a3301421d9.png)|NX_KEYTYPE_SOUND_UP|
|![eject.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283293/95226970-03b2-c7b9-897c-9eb9832cfc1f.png)|NX_KEYTYPE_EJECT|


上のものも含めて、キータイプは下記の通り記述されている。いくつか試したが、機能しているかどうか確認できなかったものが多かった。


```swift:IOKit.hidsystem
public var NX_NOSPECIALKEY: Int32 { get }
public var NX_KEYTYPE_SOUND_UP: Int32 { get }
public var NX_KEYTYPE_SOUND_DOWN: Int32 { get }
public var NX_KEYTYPE_BRIGHTNESS_UP: Int32 { get }
public var NX_KEYTYPE_BRIGHTNESS_DOWN: Int32 { get }
public var NX_KEYTYPE_CAPS_LOCK: Int32 { get }
public var NX_KEYTYPE_HELP: Int32 { get }
public var NX_POWER_KEY: Int32 { get }
public var NX_KEYTYPE_MUTE: Int32 { get }
public var NX_UP_ARROW_KEY: Int32 { get }
public var NX_DOWN_ARROW_KEY: Int32 { get }
public var NX_KEYTYPE_NUM_LOCK: Int32 { get }

public var NX_KEYTYPE_CONTRAST_UP: Int32 { get }
public var NX_KEYTYPE_CONTRAST_DOWN: Int32 { get }
public var NX_KEYTYPE_LAUNCH_PANEL: Int32 { get }
public var NX_KEYTYPE_EJECT: Int32 { get }
public var NX_KEYTYPE_VIDMIRROR: Int32 { get }

public var NX_KEYTYPE_PLAY: Int32 { get }
public var NX_KEYTYPE_NEXT: Int32 { get }
public var NX_KEYTYPE_PREVIOUS: Int32 { get }
public var NX_KEYTYPE_FAST: Int32 { get }
public var NX_KEYTYPE_REWIND: Int32 { get }

public var NX_KEYTYPE_ILLUMINATION_UP: Int32 { get }
public var NX_KEYTYPE_ILLUMINATION_DOWN: Int32 { get }
public var NX_KEYTYPE_ILLUMINATION_TOGGLE: Int32 { get }
```

[**このファイル**の定数](https://github.com/apple-oss-distributions/IOHIDFamily/blob/07b14847cb5b4e0f826a3970961624969e443a6e/IOHIDSystem/IOKit/hidsystem/ev_keymap.h)をSwiftで宣言しただけと思われる。_（[NeXT](https://www.nextcomputers.org)が懐かしい）_


なお、上記のコードをはじめて実行すると、システム環境設定のプライバシーが開くので、該当appにアクセシビリティの制御許可を与える必要があります。

_インテルMacbook Pro / macOS 11.6 / Xcode 13.1 / Swift 5.5.1 で動作確認済み_




# 参考


- 以下のPythonコードを参考にした。

https://newbedev.com/emulate-media-key-press-on-mac


- キーボードとマウスのエミュレート方法は↓この記事にあります。

https://qiita.com/Kyome/items/33143418d061fd7ec7d6