過去の記事では OBS の外部からの操作や、それを Slack と連携させてみたり、その他 MQTT とともに IoT系の話で使っている WebSocket。
●「websocket user:youtoy」の検索結果 - Qiita
https://qiita.com/search?q=websocket+user%3Ayoutoy
この WebSocket を p5.js Web Editor 上で使って、何か面白い外部連携的なことができないかな、とふと思ったのがこの記事を書いたきっかけです。
それで、まずは WebSocket を利用するプログラムと、お手軽に試せそうな外部連携を試してみます。
(wscat を使った動作確認と、OBS のシーン切り替えをやってみます)
WebSocket について
リアルタイム通信でおなじみの WebSocket。
Web系の情報を調べるのにいつもお世話になる MDN のサイトでは、以下のページなどに情報が書かれています。
●WebSocket - Web API | MDN
https://developer.mozilla.org/ja/docs/Web/API/WebSocket
冒頭に書いた MQTT だと、ブラウザ上で動かすのに MQTT.js等のライブラリが必要ですが、WebSocket であればライブラリ不要で呼び出せます。
ひとまず、シンプルな構成のものを試すため、上記のページのサンプルを見つつ実装をしてみます。
WebSocket の基本の処理
上記の MDN のページに書かれたサンプルを以下に転載してみます。
// WebSocket 接続を作成
const socket = new WebSocket('ws://localhost:8080');
// 接続が開いたときのイベント
socket.addEventListener('open', function (event) {
socket.send('Hello Server!');
});
// メッセージの待ち受け
socket.addEventListener('message', function (event) {
console.log('Message from server ', event.data);
});
上記の1つ目のブロックは、接続を行うための処理で、ローカルにポート番号 8080 でサーバーを立てている前提になっています。
上記の 2つ目のブロックは、接続が確立された際の処理と、その接続確立時にサーバーへメッセージを送る処理が書かれています。
3つ目のブロックは、サーバーにメッセージが送られたものを受けとる部分の処理です。
サーバーの準備(wscat を利用)
WebSocket用のサーバーの準備に関して、もし npmコマンドが使える状態であれば、wscat を利用するのが手軽かもしれません。
今回はこの方法を使って進めます。
その他、以下の記事で扱った OBSの外部からの制御については、WebSocketプラグインを導入してそれを立ち上げれば、OBS のプラグインがローカルにサーバーを立ててくれたりします。
●OBS をスマホや M5GO(M5Stack)から遠隔制御 〜 MQTT や obs-websocket を利用 〜 - Qiita
https://qiita.com/youtoy/items/23fb0e16f1a4428b5c9b
wscat を使って軽いお試し
とりあえず上で少し書いていた wscat を使ってサーバーを立ち上げてみます。
wscat を使った処理
以下の記事を書いた際には、wscat のインストール&実行に npx コマンドを使って一時的なパッケージインストールを行っていました。
●WebSocket のサーバー・クライアントをコマンドラインで簡単に実行する(npx と wscat) - Qiita
https://qiita.com/youtoy/items/72bbd5f6b0893756da36
今回は、「ローカルインストールを用いて、それを npx コマンドで実行する」という別のやり方で進めてみます。
そこで今回は、グローバルインストールで wscat を準備して進めていきます。
まずは、適当なフォルダで以下を実行します。
$ npm install -g wscat
その後、以下のコマンドを使い、ポート番号 8080 を指定してサーバーを立ち上げます。
$ npx wscat -l 8080
以下は Mac のターミナル上で実行した例ですが、「8080ポートで待ち受け中」というメッセージが表示された状態になります。
p5.js Web Editor から WebSocketサーバーへメッセージ送信
それでは、p5.js Web Editor でプログラムを書いて、WebSocketサーバーへ接続してメッセージを送信してみます。
キャンバスや背景色の指定は残しつつ、 draw()
の中で処理を行わないので一旦 noLoop();
を適用しています。
そしてメッセージ送信のトリガーはマウスクリックにして、クリック時にサーバーにメッセージが送られるという実装を加えています。
let socket;
function setup() {
createCanvas(400, 400);
background(220);
noLoop();
socket = new WebSocket("ws://localhost:8080");
socket.addEventListener("open", function (event) {
console.log("OK!");
});
}
function draw() {}
function mousePressed() {
if (socket) {
socket.send("Hello Server!");
}
return false;
}
先ほどコマンドで立ち上げたサーバーはそのままで上記のプログラムを実行し、マウスのクリックイベントを 1回発生させると、以下のようになることが確認できます。
上の画像 3行目の出力で、p5.js Web Editor側からの接続が完了できたことと、4行目の出力で socket.send("Hello Server!");
を 1回実行してみた際(マスクのクリックをしてみた際)の出力がサーバー側に届いていることが確認できました。
p5.js Web Editor で WebSocketサーバーからのメッセージを受信する
今度は、p5.js Web Editor がメッセージを受けとる側の処理を試してみます。
そのためには、p5.js Web Editor へメッセージを送る役割のものが必要になりますが、先ほど立ち上げた wscat の WebSocketサーバーがその役割を担えるので、それで進めます。
MDN のサイトのサンプルを見つつ、p5.js Web Editor 上でメッセージを受信する側のプログラムも実装してみます。
let socket;
function setup() {
createCanvas(400, 400);
background(220);
noLoop();
socket = new WebSocket("ws://localhost:8080");
socket.addEventListener("open", function (event) {
console.log("OK!");
});
socket.addEventListener("message", function (event) {
console.log("Message from server ", event.data);
});
}
function draw() {}
function mousePressed() {
if (socket) {
socket.send("Hello Server!");
}
return false;
}
追加したのは、 socket.addEventListener("message", function (event) {...}
の部分です。
それでは、WebSocketサーバーが立ち上がった状態で、上記のプログラムも実行しつつ、サーバー側からメッセージを送ってみます。
先ほどの状態で、サーバー側の最後の行が「>
」と表示された状態になっていますが、そこで「Hello!!」など適当な文字列を入力して実行してみます。
そうすると、サーバーからクライアントへのメッセージ送信が行われます。
p5.js Web Editor側のコンソールを確認してみると、以下のような表示がされているのを確認できました。
サーバー側で入力したメッセージを受信できているのが分かります。
wscat でのクライアントの実行について補足
今回、p5.js Web Editor へメッセージを送る際、wscat で用意したサーバーを用いました。
wscat には、コマンドでクライアントを準備する仕組みもあります。
それを一時的なインストール(※ npx によるインストール)やローカルでのインストール(※ 上記のやり方)を用いた場合、以下のコマンドでサーバーに接続した際に「code: 1006, reason: ""
」というメッセージが出て、クライアントが終了してしまう状態になりました。
$ npx wscat -c ws://localhost:8080
現状、wscat でクライアントを準備したい場合、公式のインストール方法で書かれている以下のグローバルインストールを用いるのが無難なようです。
$ npm install -g wscat
上記でインストールした場合、サーバー・クライアントを実行するコマンドは以下となります。
# サーバー側
$ wscat -l 8080
# クライアント側
$ wscat -c ws://localhost:8080
OBS と p5.js Web Editor を連携させてみる
あともう 1つお試しをしてみます。
具体的には OBS のシーン切り替えを p5.js Web Editor から実行してみます。
OBS のプラグインを準備する
そのためには、過去の記事でも扱った以下のプラグインを使いますが、詳細は過去の記事の説明などをご覧ください。
●obs-websocket - Remote-control OBS Studio from WebSockets | OBS Forums
https://obsproject.com/forum/resources/obs-websocket-remote-control-obs-studio-from-websockets.466/
●Palakis/obs-websocket: Remote-control OBS Studio through WebSockets
https://github.com/Palakis/obs-websocket
OBS にプラグインを導入すると、OBS のメニューの「ツール」の中に上記のプラグインに関するメニューが追加されます。
これを開いて、適宜設定を変更して利用します。
「サーバーポート」は他の別のプログラム等で使われてなければ、デフォルト設定で大丈夫ですが、何らか衝突が起こった際は変更をしておきましょう。
また、「認証を有効にする」の項目は、利用手順が少し複雑になるので今回はチェックを外しています。
そもそも今回は OBS をローカルで動作させており、OBS上から動作開始をさせている間だけ動くもので、その PC に外部から接続できる経路がない状態なので、この設定を外しています。
(OBS を第3者が利用可能な、クラウド上で動作させている状況などといった場合は、条件が変わってきますので適宜設定を変更してください)
OBS のシーンを複数準備する
今回は OBS のシーン切り替えを p5.js Web Editor から行います。
その切り替え対象となる複数のシーンを、OBS上で準備します。
自分は、過去の記事を書いた際に用意したものを流用します。
ここでの設定に関して、「シーンの名称」は、この後で利用することになります。
p5.js Web Editor のプログラム
上記の通り OBS上で 3つのシーンを用意しました。
その切り替えは、マウスクリックでなく数字キーの入力で行う形にしてみます。
以下の公式リファレンスの中の「key
」のほうで判別する処理を書いていきます。
●reference | keyCode
https://p5js.org/reference/#/p5/keyCode
また、シーン切り替えを行う際は JSON を送る必要があります。
以下の記事に書いた、公式の仕様で規定されたシーン切り替え用のフォーマットで送信してみます。
●Node-RED を使って OBS を遠隔操作してみた話(obs-websocket を利用)|豊田 陽介|note
https://note.com/youtoy/n/nf404040a91c0
{
"request-type":"SetCurrentScene",
"message-id":"(適当に決めたID)",
"scene-name":"(OBS上で設定したシーンの名前)"
}
プログラムは以下の通りです。
"(適当に決めたID)"
と "(OBS上で設定したシーンの名前)"
という部分が 3箇所ありますが、ここは適宜書きかえてご利用ください。
let socket;
const sceneJSON = [
{
"request-type": "SetCurrentScene",
"message-id": "(適当に決めたID1)",
"scene-name": "(OBS上で設定したシーンの名前1)",
},
{
"request-type": "SetCurrentScene",
"message-id": "(適当に決めたID2)",
"scene-name": "(OBS上で設定したシーンの名前2)",
},
{
"request-type": "SetCurrentScene",
"message-id": "(適当に決めたID3)",
"scene-name": "(OBS上で設定したシーンの名前3)",
},
];
function setup() {
createCanvas(400, 400);
background(220);
noLoop();
socket = new WebSocket("ws://localhost:4445");
socket.addEventListener("open", function (event) {
console.log("OK!");
});
socket.addEventListener("message", function (event) {
console.log("Message from server ", event.data);
});
}
function draw() {}
function keyPressed() {
switch (key) {
case "1":
socket.send(JSON.stringify(sceneJSON[0]));
break;
case "2":
socket.send(JSON.stringify(sceneJSON[1]));
break;
case "3":
socket.send(JSON.stringify(sceneJSON[2]));
break;
default:
break;
}
}
OBS を起動してプラグインを実行した状態で、さらに上記を実行して数字キー(1 or 2 or 3)を押すと、OBS上のシーンが切り替わるのを確認できました。
まとめ
今回、p5.js Web Editor上のプログラムで WebSocket を扱い、wscat で立てたローカルの WebSocket との通信や、プラグインを導入した OBS の操作を行ってみました。
とりあえず今回は過去のリソースなどを利用し、手軽に実行できそうな例でやってましたが、「ガジェット・ハードウェア連携」や「PC と スマホのそれぞれのブラウザ間での連携」などで活用すると面白いことができそうです。
また、リアルタイム通信系の JavaScript実装は、個人的には MQTT をよく使っていたので、以前よく使ったこともある MQTT.js のブラウザ版の処理を用いたものも試せればと思います。
●「mqtt user:youtoy」の検索結果 - Qiita
https://qiita.com/search?q=mqtt+user%3Ayoutoy
【追記】 MQTTバージョンも記事にしました! & お試し
MQTT を使った場合の実装方法について、記事を書きました!
●p5.js Web Editor で MQTT を扱ってみる(MQTT.js や shiftr.io Desktop を利用) - Qiita
https://qiita.com/youtoy/items/7c58de69b4b20543a5b5
また、このようなことを MQTTバージョンのほうで試したりしました。
先日、 #p5js のプログラムにリアルタイム通信の仕組み(WebSocket、MQTT)を試しに組み込んだものを活用して、MacBook と iPad の間でのリアルタイム通信を試した!
— you (@youtoy) August 20, 2021
MacBook のブラウザと iPad のブラウザの表示領域との間を、動く円が行き来するような表示がされるプログラムを書いてみた。 pic.twitter.com/DgHpIdBljF
この前試した、 #p5js とリアルタイム通信(MQTT)の組み合わせで MacBook と iPad のそれぞれの画面間をつないだような処理をやった話の発展形!
— you (@youtoy) August 26, 2021
今度は、スマホ 2台の画面をつないだのですが、その2つの画面のつながる方向が、動的に縦方向だったり横方向だったり、変化するような実装にしてみた! pic.twitter.com/WmCev0oBfx