この記事はIoTLTアドベントカレンダー1日目です!(先に断っておきますが自作キーボード話ではないです) 先日のIoTLT vol69で話したネタをアップデートした感じです。
関係ないけどついに、この季節がやってきましたか〜 2020年めちゃ早い
IoTLT vol69 https://iotlt.connpass.com/event/192582/
テンション爆上がりなキーボードがこちら
クリスマスソングに合わせてキーボードを光らせる! #iotlt の #アドベントカレンダー2020 向けのやつです。 pic.twitter.com/pWqOULx8nX
— 菅原のびすけ (@n0bisuke) December 1, 2020
毎年アドベントカレンダーネタでクリスマスっぽい話をやろうかと思ってたけど、全然やれてなかったので今回はクリスマス曲に合わせてみました。
記事の後半に実際に試せる(MacBookProでしか試してませんが)ページのURLを記載してますので是非手元でも試してみてください!
ちなみに再生してる曲はこちらから
なんとブラウザでキーボードバックライトの制御
Webブラウザからキーボードバックライトを制御出来ています。
ブラウザからハードウェアが制御できるAPIは色々と試して来てますが、今回は特に面白いですね。
WebHID API - Nintendo Switchも動かせるよ
HIDはhuman interface devices
の略です。様々なヒューマンインターフェイスデバイスをJavaSciprtで制御出来るAPIです。
参考記事から引用: ヒューマン インターフェース デバイス(HID)には、新しすぎる、古すぎる、あまりにも一般的でないなどの理由で、システムのデバイス ドライバーからアクセスできないロングテールなものがあります。WebHID API は、デバイス固有のロジックを JavaScript で実装する方法を提供することで、この問題を解決します。
ヒューマンインターフェイスデバイスと言われてもよく分からないと思いますが、 **Nintendo Switchのコントローラー(Joy-Con)**や冒頭のデモ動画のような キーボードのバックライトの制御が出来ます。
詳細は参考記事を読んでみてください。
利用はChrome v86以上かつ、現状オリジントライアル
WebHID APIは現時点だと、Google Chrome v86以上で対応しています。
他のブラウザの対応状況はCan I Useを見て確認しましょう。
2020/12/1現在 まだ全然対応してない......
https://caniuse.com/?search=webhid
見てみると全然対応してないですね、最新版のChromeでもアップデートしただけでは使えず、オリジントライアルという利用するオリジン(利用するサイト的な)の登録作業をし、利用するユーザーのChromeのフラグ設定を変えてやっと利用出来ます。
Gamepad APIとの違いは?
Gamepad APIというものが既存で存在しましたが、Nintendo SwitchのJoy-Conが使えるとなると、このAPIとの違いは?と思う人もいるかもしれません。(この辺のハードウェア制御系のブラウザAPIをウォッチしてる人が少なさそうですが苦笑)
間違ってるかもですが僕が見ている印象だと、Gamepad API
はインプットのみでWebHID API
の方がやれることは多そうな印象でした。
- Gamepad API
-
デバイス -> ブラウザ
のインプットのみ - ゲームパッドのみ
-
- WebHID API
-
デバイス <-> ブラウザ
でインプットとアウトプット両方 - ゲームパッド以外も対応
-
上位互換というよりかは、Gamepad APIはゲームパッドからのインプットに特化してる気がします。ちゃんと調べ切れてないので、認識間違ってたらコメント下さい。
WebHID APIを利用してみよう
では実際にWebHID APIを利用してみましょう。
事前準備
最初にちょっと準備が必要です。
クライアント(ブラウザ)側
フラグを確認する必要があります。chrome://flags/
にアドレスバーからアクセスしま、#experimental-web-platform-features
のフラグをenable
にしましょう。
サーバー側、オリジンの申請
WebHID APIは、現状オリジントライアルというステータスで、利用するオリジンをGoogleに申請する必要があります。
こちらからオリジントライアル申請します。
ドメインだけでなく、オリジンなのでちゃんとhttps://
も入れましょう。
- パスは不要です。
- 例えば
https://hogehoge.com/huga/index.html
で利用したい場合はhttps://hogehoge.com
を登録すれば大丈夫です。
- 例えば
- SSLがマストです。
-
http
は使えません、https
がマストです。
-
無事に登録できると次のページでトークンが発行されます。
利用するページのHTMLファイルのmetaタグに以下のような指定をし、発行されたトークンを指定することでWebHID APIが利用出来ます。
<meta http-equiv="origin-trial" content="TOKEN_GOES_HERE">
補足: npxで気軽にサーバー起動とトンネリング
オリジンの登録ということは、基本ホスティング環境ということになりますが、毎回デプロイしなおすのは手間なので、最近はserveとngrokの二つのコマンドをnpx経由でインストールせずに実行して手軽に試してます。
- ローカルサーバー起動
$ npx serve -l 4444
- トンネリングサーバー起動
$ npx ngrok http 4444
ngrokで発行されたオリジンをオリジントライアルに登録するとデプロイなどせずに手軽に試せます
コードの実装
index.html
とscript.js
を作成しました。
HTML側 - トークンの指定
先ほども紹介したように、index.html
のhead内に以下を記載しましょう。
<meta http-equiv="origin-trial" content="TOKEN_GOES_HERE">
TOKEN_GOES_HEREの箇所は登録して発行されたトークンです。
JavaScript側 - navigator.hid
script.js
は以下のコードで実行してみます。
利用できる状態だと、navigator.hid
が利用出来ます。
if ("hid" in navigator) {
// The WebHID API is supported.
console.log(`HIDが使えるよ`);
} else {
console.log(`HIDが使えません`);
}
コンソールにHIDが使えるよ
と表示されればOKです。
https://~~
で登録してるのにブラウザで確認するときにhttp://~~
になってるなど登録した条件と違う場合は動作しないので注意しましょう。
Nintendo Switchのコントローラーで試す
そのまま実行すると怒られるのでボタンを追加して、ボタンクリックからスタートするようにします。
Uncaught (in promise) DOMException: Failed to execute 'requestDevice' on 'HID': Must be handling a user gesture to show a permission request.
web.devのサンプルコードからそのままという感じですが、Nintendo SwitchのJoy-ConはvendorId
やproductId
が↓のような値なので指定しましょう。
// Filter on devices with the Nintendo Switch Joy-Con USB Vendor/Product IDs.
const filters = [
{
vendorId: 0x057e, // Nintendo Co., Ltd
productId: 0x2006 // Joy-Con Left
},
{
vendorId: 0x057e, // Nintendo Co., Ltd
productId: 0x2007 // Joy-Con Right
}
];
const main = async () => {
// Prompt user to select a Joy-Con device.
const [device] = await navigator.hid.requestDevice({ filters });
};
if ("hid" in navigator) {
// The WebHID API is supported.
console.log(`HIDが使えるよ`);
const btn = document.querySelector(`button`);
btn.addEventListener('click', main);
}else{
console.log(`HIDが使えません`);
}
Webサイトにアクセスし、スタートボタンを押すと接続済みのJoy-ConがHIDとして認識されます。
また、このような実装まで繋げてあげると、 Joy-Conのバイブレーション機能を利用出来ます。
// First, send a command to enable vibration.
// Magical bytes come from https://github.com/mzyy94/joycon-toolweb
const enableVibrationData = [1, 0, 1, 64, 64, 0, 1, 64, 64, 0x48, 0x01];
await device.sendReport(0x01, new Uint8Array(enableVibrationData));
// Then, send a command to make the Joy-Con device rumble.
// Actual bytes are available in the sample below.
const rumbleData = [ /* ... */ ];
await device.sendReport(0x10, new Uint8Array(rumbleData));
device.sendReport()
でデータ配列を送ってバイブを制御しています。
ここのデータを変えて試してみたいですね。
キーボードバックライトで試す
同じようなアクセスの仕方で、キーボードのバックライトをJavaScriptから制御できます。
vendorIdなどのパラメータも参考記事を元に指定します。
const [device] = await navigator.hid.requestDevice({
filters: [{ vendorId: 0x05ac, usage: 0x0f, usagePage: 0xff00 }]
});
リクエストするとKeyboard Backlight
の許可を求められます。
// Blink!
const reportId = 1;
for (let i = 0; i < 10; i++) {
// Turn off
await device.sendFeatureReport(reportId, Uint32Array.from([0, 0]));
await waitFor(100);
// Turn on
await device.sendFeatureReport(reportId, Uint32Array.from([512, 0]));
await waitFor(100);
}
音楽に合わせてキーボード光らせるのはこちらで試せます
最後ですが、ここまで試して、キーボードを光らせることが出来たので、音楽にノらせてパリピ感のある演出をしてみたいなと突発的に思いました。これが最初のデモになります。
Izm Logさんのブログを参考に、ビート検出のコードを利用させてもらい、 ビート検出時にキーボードを光らせる というプログラムを作ってみましたが、けっこういい感じの反応になりました。
デモ動画の最後にも載せてますが、指パッチンでの反応もいい感じです。
MacBookProでしか試せてませんが、こちら↓で試せます。
- マイクの利用を許可する
- リクエストのボタンを押す
- デバイス利用の許可を求められるので、
Keyboard Backlight
を選択- (MacBookPro以外の人はここでデバイスが表示されないかも)
- オープンのボタンを押す
- このページを開きながら、何か音楽を流す
- この時、別タブでYoutubeを長そうとすると、このページの処理が止まってしまうので、一つのPC内で試す際は別タブではなく
別ウィンドウ
で開くようにしましょう。このページがアクティブになってる状態にして下さい。
- この時、別タブでYoutubeを長そうとすると、このページの処理が止まってしまうので、一つのPC内で試す際は別タブではなく
まとめ
色々と書きましたが、Chrome v86から利用できるようになったWebHID APIを利用してみたという記事です。
まだGoogle公式のサンプルを少しいじったくらいしか試せてませんが、キーボードのバックライトをいじれるのはけっこう楽しいです。
Nintendo Switchのコントローラーもまだまだ遊びきれてないのでまた少し触ってみたいなぁ
前回のIoTLT vol69の時の様子はこちらのYoutubeでも観れるのでぜひご覧ください!そしてチャンネル登録も是非!
次回は12/15にIoTLTを実施しますのでこちらもよろしくお願いします!
明日は@3yaka4さんによるねこIoT
的な何かの記事です!
楽しみですね〜 :)
少し早いですが、今年もありがとうございました!来年もよろしくお願いします!
それでは!