Joy-Con 2 をブラウザ上で Bluetooth 接続し、スライドサービス上でスライド送り・戻しをできるようにしてみました。
-
必要要件
- Bluetooth 接続が可能であること
- OS
-
Web Bluetooth API をサポートするブラウザ
- Google Chrome
- Microsoft Edge
-
検証した環境
- MacBook Pro (14-inch, M1 Pro)
- macOS Sequoia
- Chrome 137
- Joy-Con 2 (L)
Google スライドなどのスライドサービス上でコンソールを開き、以下のスクリプトを実行します:
(async(e,t,a)=>{let i=!1;const n=(t,a)=>{const i=e.activeElement,n="IFRAME"===i.tagName?i.contentDocument:e;["keydown","keyup"].forEach(e=>{n.body.dispatchEvent(new KeyboardEvent(e,{key:t,keyCode:a,bubbles:!0}))})},c="ab7de9be-89fe-49ad-828f-118f09df7fd0",r=await t.bluetooth.requestDevice({filters:[{manufacturerData:[{companyIdentifier:1363,dataPrefix:new a([0,0,0,0,0,103,32]),mask:new a([0,0,0,0,0,255,255])}]}],optionalServices:[c]}),o=await r.gatt.connect(),s=await o.getPrimaryService(c),d=await s.getCharacteristic("ab7de9be-89fe-49ad-828f-118f09df7fd2");if(await d.startNotifications(),d.addEventListener("characteristicvaluechanged",e=>{const t=e.target.value.getUint8(6);i=8&t?(!i&&n("ArrowLeft",37),!0):!!(4&t)&&(!i&&n("ArrowRight",39),!0)}),t.wakeLock){const a=i=>{"visible"===e.visibilityState&&t.wakeLock.request("screen").then(()=>{i&&(e.addEventListener("visibilitychange",a),e.addEventListener("fullscreenchange",a))},()=>{})};a(!0)}})(document,navigator,Uint8Array);
Bluetooth デバイスを選択するダイアログが表示されたら、Joy-Con 2 (L) のシンクロボタンを押して LED ランプが点滅している間にペア設定をします:
ペア設定後、左矢印ボタン・右矢印ボタンを押すと、スライドサービス上でスライド送り・戻しができるようになります。
このスクリプトでは dispatchEvent
で左矢印キー・右矢印キーを押したときのイベント(keydown
と keyup
)を発火することで、大半のスライドサービスでスライド送り・戻しができるようになっています。
また、プレゼン中に画面がスリープしないようにするため、Screen Wake Lock API を利用しています。
ページを再読み込みしたり、閉じたりすると Joy-Con 2 との接続が解除されます。再接続するには、もう一度スクリプトを実行してください。
事前調査
Switch 2 を入手する前から SNS 上の投稿をチェックしていましたが、Windows, macOS ともに Joy-Con 2 の検知すらできないという報告がいくつかありました。実機を入手してから macOS で接続を試みたところ、事前情報の通りデバイスの検知もできませんでした。
GitHub 上で Joy-Con 2 に関連していそうなリポジトリを探してみたところ、Joy-Con 2 は Bluetooth Advertisements という仕組みを利用していることがわかりました。
Claude に相談し、LightBlue というアプリで Advertisements を拾うことができることを教えてもらいました:
Q: macOS で BLE advertisements を拾うことはできる?
A: はい、macOS で BLE advertisements(BLE アドバタイズメント)を拾うことは可能です。いくつかの方法があります:
- サードパーティツール
- LightBlue Explorer(Mac App Store)
- (省略)
LightBlue で接続してみる
LightBlue であれば Joy-Con 2 の接続ができること、ボタンの状態を取得できることがわかりました。
Web Bluetooth API で実装
macOS でも Bluetooth 接続してボタンの状態を取得できることがわかったので、Web Bluetooth API での実装にチャレンジしてみることにしました。
navigator.bluetooth.requestDevice
を使うか navigator.bluetooth.requestLEScan
を使うかの判断に悩みましたが、これも Claude に相談して前者を使えば良いことを教えてもらいました:
Q: BLE advertisement を利用してペアリングするらしいのですが、requestLEScan を使う必要はありますか?
A: いいえ、requestLEScan を使う必要はありません。navigator.bluetooth.requestDevice()だけで BLE advertisement を利用したペアリングが可能です。
Claude でサンプルコードを生成してもらい、LightBlue で取得した Service UUID と Characteristic UUID を組み込んだり Chrome 上で出たエラーをデバッグすることで、Joy-Con 2 との接続とボタン状態の取得ができました。
デモページ公開
macOS 以外の環境で動作する確証はなかったため、Vue.js でデモページを作成して公開し、macOS 以外で動作しそうな OS (Windows, Android) の環境をお持ちの方に検証の呼びかけをしました。
大変ありがたいことに、X 上で Windows 11 と Android での動作報告をいただきました。
Joy-Con 1 (L) をプレゼンリモコンにする
Joy-Con 1 は Windows や macOS がゲームパッドとして認識してくれるため、Gamepad API を利用して実現しています。
左矢印キー・右矢印キーのイベントを発火する処理は、このときのものを流用しています。
リングフィットアドベンチャーのリングコン
リングコンのチカラセンサーの値もブラウザ上に表示できます。
Gamepad API では Joy-Con 1 のボタン状態やスティック位置を取得できますが、ジャイロセンサーやリングコンのチカラセンサーの値は取得できないため、WebHID API を利用して実現しています。
公開したデモのコードが IchigoJam web に移植され、リングコンと BASIC 言語でミニゲームを作って楽しめるようになっています:
なお、リングコンをプレゼンリモコンにするスクリプトも公開していますので、筋肉質なプレゼンをやりたい方におすすめしておきます: https://github.com/mascii/demo-of-ring-con-with-web-hid/blob/main/presentation-ring-con.js
AI と壁打ちしていたら、Web Bluetooth API で Joy-Con 2 を接続できるようになっていました。
Views: 0