水底

ScalaとかC#とかk8sとか

VoicemeeterでBluetoothデバイス接続時の挙動を改善する

Voicemeeter環境で特定のBluetoothイヤホンを接続したときにAudio Engineを自動でRestartさせるまでの備忘録です.

まず前提として,VoicemeeterのHardware Outにデバイスを登録しても再接続時に自動的に利用できるようにはならず(画面的には以下のAirPods Proのように赤文字のまま再接続されない),特に付け外しが多いBluetoothイヤホンの接続時に毎回手動でのRestartが必要で不便でした.一応,VoicemeeterにはA1もしくは任意のデバイス接続時にAudio EngineをRestartさせるオプション (Auto Restart Audio Engine (A1 Device), Auto Restart Audio Engine (All Devices)) がありますが,これらは対象のデバイスが接続されていないと定期的にRestartをかけてしまうため,未接続時には音声が飛びまくって使い物になりません.

方針

Bluetoothイヤホン接続イベント発生時にVoicemeeterのRestartをkickする.

環境

  • Windows11 10.0.22000 Build 22000
  • Voicemeeter Potato 3.0.2.2

詳細

  1. VoicemeeterをCLIから操作するためのツールをインストール
  2. vmcliのバックグラウンド実行用VBスクリプトを作成
    • vmcliを直接叩くとその度にコマンドプロンプト画面が出てしまうのを防ぐため
    •   Set ws = CreateObject("Wscript.Shell")
        ws.run "cmd /c 【vmcliのパス】 Command.Restart=1", vbhide
      
    • インストール先は任意
  3. Bluetooth接続イベントログを有効化
    • Event Viewerを開き,Applications and Services Logs > Microsoft > Windows > Bluetooth-Policy > Operationalコンテキストメニューから Enable Log を選択
      • デフォルトでは無効になっているはず
  4. 対象のBluetoothバイスのアドレスを確認
    • Bluetooth接続イベントログを有効化した状態で実際に接続すると Event ID=9 としてログが吐かれるので,Event Properties > DetailsEventData > bthAddr をメモ
      • 多分15桁の数値
  5. Task Schedulerの設定
    • Task Schedulerを開き,てきとうなディレクトリで Create Task
      • お作法をよくわかっていないが,Task Scheduler Library/Users を作っておいた
    • 以下を設定
      • General > Name: てきとう
      • Trigger > New: Begin the task=On an event
        • Settings > Custom > New Event FilterXMLタブから Edit query manually を有効化して以下を入力
          • 対象のBluetoothバイスのbthAddrはイベントログからメモったもの
          •   <QueryList>
                  <Query Id="0" Path="Microsoft-Windows-Bluetooth-Policy/Operational">
                      <Select Path="Microsoft-Windows-Bluetooth-Policy/Operational">
                          *[System[Provider[@Name='Microsoft-Windows-Bluetooth-Policy'] and EventID=9]] and *[EventData[Data=【対象のBluetoothデバイスのbthAddr】]]
                      </Select>
                  </Query>
              </QueryList>
            
      • Actions > New: Action=Start a program Program/script=【作成したVBスクリプトのパス】
      • その他の設定はデフォルトでok

これで指定のBluetoothバイスが接続されたタイミングで自動的にVoicemeeterがRestartされすぐに使えるようになりました.ちなみに,VBスクリプトの部分をいじれば「Bluetoothイヤホン接続時にはスピーカーをMuteする (ws.run "cmd /c 【vmcliのパス】 Bus[1].Mute=1", vbhide を追加)」みたいなこともできますね.便利.

本当はUSBデバイスでも同様のことがしたかったのですが,うまいことイベントを拾えないケースがありとりあえずBluetoothのみになりました.