🐍

XSOverlayの手首メニューのメディアキーを自分のアプリの制御に利用する方法

2023/12/05に公開

概要

pynputライブラリを利用したキーボードのグローバルフックによって、XSOverlayの手首メニューの「前の曲」「再生/一時停止」「次の曲」キーが押されたことを検知し、自分のアプリでお好みの処理を実行。その後、メディアプレーヤーなどの他のアプリが動いてしまわないようにキー入力のメッセージを破棄します。

手首メニューのメディアキーが押された時に情報を飛ばしてくれるような専用のAPIやアドオンをXSOverlayが用意してくれているわけではありません。

XSOverlayの手首メニューの各メディアキーの場所

環境

  • Windows10 64bit
  • Python 3.7.5
  • pynput 1.7.6
  • XSOverlay Build 645 (BuildID 12586499)

pythonコード

from pynput import keyboard

def win32_event_filter(msg, data):
    # msg >> キー下げ:257、キー上げ:256
    # data.vkCode >> 前の曲:0xB1、再生/一時停止:0xB3、次の曲:0xB0

    # 「前の曲」キーの処理
    if 0xB1 == data.vkCode:
        if 257 == msg:                          # キー下げ
            print("Pushed PreviousTrack key")   # お好みの処理を実行
        listener.suppress_event()               # キー入力のメッセージを破棄
    
    # 「再生/一時停止」キーの処理
    if 0xB3 == data.vkCode:
        if 257 == msg:                          # キー下げ
            print("Pushed Play/Pause key")      # お好みの処理を実行
        listener.suppress_event()               # キー入力のメッセージを破棄

    # 「次の曲」キーの処理
    if 0xB0 == data.vkCode:
        if 257 == msg:                          # キー下げ
            print("Pushed NextTrack key")       # お好みの処理を実行
        listener.suppress_event()               # キー入力のメッセージを破棄

# キーボード入力監視リスナー開始
with keyboard.Listener(on_press=None, on_release=None, win32_event_filter=win32_event_filter, suppress=False) as listener:
    listener.join()

注意点

  • 当然ですが、メディアキー入力のメッセージを破棄しているため、XSOverlayの手首メニューからのメディアプレーヤーの再生/停止、曲送りなとの操作はできなくなります。また、メディアキー付きのキーボードからのメディアプレーヤーの操作も同様に行えなくなります。
  • XSOverlayの仕様上メディアキーの長押し判定が現状取れません。XSOverlayのメディアキーを押しただけではキー入力のメッセージは送られず、キーを離したときに「キー下げ」と「キー上げ」のメッセージが連続して送られてきます。
  • 特定のメディアプレーヤー(AIMP3)を、本コードよりも後に実行するとlistener.suppress_event()が効かず、再生/停止、曲送りなとの操作ができてしまう場合があります。(AIMP3もグローバルフックを利用している??)
  • お好みの処理部分で、時間のかかる処理を行うとlistener.suppress_event()が効かないことがありました。その場合は、お好みの処理を関数化しスレッドとして実行することで、メディアキー入力を抑制できます。

参考サイト

この仕組みを利用した例

VRChatで日頃繰り返し行っていたXSOverlayによるデスクトップ画面上のマウス・キーボード操作を自動化するアプリに利用しました。
https://booth.pm/ja/items/4675444
https://booth.pm/ja/items/5308811

Discussion