やりたいこと
1つの無線イヤホンで複数(PCとiPhone)の音源をいい感じに再生したい
現状
- 再生側はBluetoothレシーバー(Fiio BTR5)から2台へマルチポイント
- PCとはBluetoothドングル(BT-W3)とapt-x接続
- iPhoneとはBluetooth接続(AAC)
不満点
コーデック差分により、マルチポイント接続においてPC側の接続が常に優先されるため、iPhone側の音を聞きたいとき、PC側のドングルを都度物理的に抜く必要がある。
解決策
用意するもの(物理)
遠隔でUSBの電源を落とすやつ
用意するもの(論理)
iPhone(Homekit)から接続対象を弄りたいので、以下を構築
1.HomeBridgeインストール
CentOS上にHomeBridgeをインストールし、HomeKitで捌くためのサーバを用意。参考URLのコマンド打ったらなんかするっと入った。
※nodeのverが古かったので、アップデートだけは以下を参考に実施。
※OS内でコマンド実行するアクセサリを構築するため、以下もインストール
2.HomeBridgeサーバ設定
-
サーバのローカルIP固定設定、Windowsとの共有フォルダ設定(/etc/fstab)、homebridgeユーザのsudore設定(Windows領域にフラグファイルをsudoでtouchできるようにする)、を実施
-
コンフィグは以下で書いたら動いた。シェルはフラグファイルをWindows領域にtouchしてるだけ。
※sudo touch /<<フラグファイル共有フォルダ>>/BT_W3_ON
{
"bridge": {
"name": "Homebridge XXXX",
"username": "XX:XX:XX:XX:XX:XX",
"port": XXXXX,
"pin": "XXX-XX-XXX",
"advertiser": "bonjour-hap"
},
"accessories": [
{
"accessory": "CMD",
"name": "BT-W3",
"on_cmd": "/home/homebridge/BT-W3.sh ON",
"off_cmd": "/home/homebridge/BT-W3.sh OFF"
}
],
"platforms": [
{
"name": "Config",
"port": XXXX,
"platform": "config"
}
]
}
#!/bin/bash
# フラグファイル配置先ディレクトリ
FLG_DIR="/sf/HomeBridgeServer"
# デバイス名(=スクリプト名)
DEV_NAME=$(basename "$0" .sh)
# 実行時引数をチェックする
if [ "$1" = "ON" ]; then
# "${FLG_DIR}/${DEV_NAME}-OFF"ファイルが存在する場合は削除する
if [ -f "${FLG_DIR}/${DEV_NAME}-OFF" ]; then
sudo mv "${FLG_DIR}/${DEV_NAME}-OFF" "${FLG_DIR}/${DEV_NAME}-ON"
else
# "${FLG_DIR}/${DEV_NAME}-ON"ファイルを生成する
sudo touch "${FLG_DIR}/${DEV_NAME}-ON"
fi
elif [ "$1" = "OFF" ]; then
# "${FLG_DIR}/${DEV_NAME}-ON"ファイルが存在する場合は削除する
if [ -f "${FLG_DIR}/${DEV_NAME}-ON" ]; then
sudo mv "${FLG_DIR}/${DEV_NAME}-ON" "${FLG_DIR}/${DEV_NAME}-OFF"
else
# "${FLG_DIR}/${DEV_NAME}-OFF"ファイルを生成する
sudo touch "${FLG_DIR}/${DEV_NAME}-OFF"
fi
else
echo "Usage: $0 [ON|OFF]"
exit 1
fi
3.USB Troubleshooter制御用(接続・切断・切替)APの作成
cppわからん...やったことは以下
- 「Microsoft Visual C++ 2010 再頒布可能パッケージ (x86) 」をインストール
- Visual Studio(2022) と C++の開発ツールを一式インストール
- 製品URLのサンプルソースをDL
-
USB_Check.vcxproj
を開く - プロジェクトを再ターゲット
- ビルドをトライ&エラーして、実行前提となる諸々をインストール。これとか。
-
USB_CheckDlg.cpp
に以下の処理を追記
// CUSB_CheckDlg メッセージ ハンドラー
BOOL CUSB_CheckDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// このダイアログのアイコンを設定します。アプリケーションのメイン ウィンドウがダイアログでない場合、
// Framework は、この設定を自動的に行います。
SetIcon(m_hIcon, TRUE); // 大きいアイコンの設定
SetIcon(m_hIcon, FALSE); // 小さいアイコンの設定
// TODO: 初期化をここに追加します。
AutoCheckExecute = FALSE;
InitGrid();
UpdateUSBInfo();
//↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓追加した処理 ここから↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓//
//デバイス情報入れるstructsを定義
USB_1PORT_HUB_DEVICE_INFO devinfo;
//デバイス情報を取得
Hub_GetDeviceInfo(&devinfo);
//USB_On.exe の場合、以下によりUSBデバイスを接続
Hub_SetStatus(devinfo.CtrlSerial, 1);//ON
//USB_Off.exe の場合、以下によりUSBデバイスを切断
Hub_SetStatus(devinfo.CtrlSerial, 0);//OFF
//USB_Switch.exeの場合、以下によりUSBデバイスの接続・切断をスイッチ
if (devinfo.ConnectionStatus) {
Hub_SetStatus(devinfo.CtrlSerial, 0);//OFF
} else {
Hub_SetStatus(devinfo.CtrlSerial, 1);//ON
}
//付属のGUIは要らないので、ここでAP自体を終了させる
EndDialog(0);
//↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑追加した処理 ここまで↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑//
return TRUE; // フォーカスをコントロールに設定した場合を除き、TRUE を返します。
}
- ↑をビルドして、
USB_On.exe,USB_Off.exe,USB_Switch.exe
の3つのexeを作って、AHKに呼ばせる
4.APの実行設定
Autohotkeyの常駐スクリプト内に以下を追加(3秒おきにTimerで実行される場所に記載)。WSLのcrontabとかタスクスケジューラーとか使ってもよいかも。
;USB_Connect用
if ( FileExist("C:\<<フラグファイル共有フォルダ>>\BT-W3-OFF") ){
FileDelete, C:\<フラグファイル共有フォルダ>>\BT-W3-OFF
run, "C:\<<USB Troubleshooterの実行ファイル配置先>>\USB_Off.exe"
}
if ( FileExist("C:\<<フラグファイル共有フォルダ>>\BT-W3-On") ){
FileDelete, C:\<<フラグファイル共有フォルダ>>\BT-W3-On
run, "C:\<<USB Troubleshooterの実行ファイル配置先>>\USB_On.exe"
}