OBSとWebSocketを使って通信するプログラムを作る時に知っておいて損がない事

配信ツールで有名なOBS Studioですが、WebSocketを使うと外部の自作プログラムから、OBSを操作できるようになります。
この記事は、これからOBSとの連携するアプリをプログラミングで作ろうとしている私と同様にプログラム初心者向けの記事となります。
私がOBSと自作アプリの連携をWebSocketで作った時に、これはこれからやる人は知っておいて損がないと思ったことを書いていきます。

外部プログラムからどこまでOBSを操作できるのか?

WebSocketを使えば、外部プログラムからOBSを結構色々操作できます。
一例として、OBSのソース内パーツの表示や非表示の切り替え、ソースに動画がある場合は再生をスタートさせたり止めたりできるし、シーンを変えることもできます。

できること一覧はgithubのOBSプロジェクトのページ、obs-websocket 5.0.0 Protocolページに掲載されています。
英語記述なので、翻訳して読む感じです。

WebSocketOBS側の設定

OBSとWebSocketで通信する場合、一昔前はobs-websocketプラグインが有名でしたが、この記事を書いている2024年現在(OBS30.2.3現在)は、最初からWebSocketプラグインがOBSに入っているので、obs-websocketプラグインをダウンロードしてわざわざインストールする必要はありません。
逆に、obs-websocketプラグインをインストールしてしまうと、正常に動作しなくなります!
また、最大の注意点は、追加でインストールしたobs-websocketプラグインをアンインストールすると、OBS内のツール(T)にある上図「WebSocketサーバー設定」も消えてしまうので注意です。
その場合は、OBS本体を1度アンインストールし、再度OBSをインストールすることで、ツール(T)に「WebSocketサーバー設定」が復活します。

OBS側は、上図のツール(T)の「WebSocketサーバー設定」でサーバーの設定を行います。

WebSocketの設定

OBS上部メニューのツール(T)からWebSocketサーバーの設定を選ぶと上のような設定画面が出ますが、特に難しい設定はなく、WebSocketサーバーを有効にするにチェックを入れます。
特に問題がなければサーバーポートは4455のままで大丈夫です。

接続する際にサーバーパスワードを設けることはできますが、それは後からでもできます。(認証を有効にする)
最初はパスワードなしで自分のプログラムから通信を成功できるかチェックしたほうが良いと思いました。

「接続されているWebSocketセッション」欄には、WebSocketの接続が成功すると、ステータスが表示されるようになります。

便利なログ機能

WebSocketのデバッグ用のエラーログを確認する方法があります。

ツール(T)からWebSocketサーバー設定内で「デバッグログを有効にする」にチェックを入れて適用すると、上図2枚目「ヘルプH」の「ログファイル(L)」の「ログファイルを表示(S)」を選ぶと出てくるテキストファイルで、WebSocketのログを確認することができます。
Socket通信でエラーが出た場合は、どんなエラーなのかも英語記述ですが知ることができるので、プログラムをコーディングしてデバッグする時にめちゃくちゃ役に立ちます。

デバッグログを有効にするの注意点

OBSを終了すると、「デバッグログを有効にする」のチェックボックスが外れるので、デバッグログを利用したい場合は、起動する度にチェックを入れないとなりません。

ログファイルを見る時に役立つ事

ログファイルはテキストファイルであるものの、膨大なログファイルから自分が送ったWebSocketデータのログがどこにあるか探すのが大変です。
お手持ちのお気に入りのテキストエディッタの検索機能で、「Incoming message」で検索することで、あなたがOBSに対してWebSocket送信したデータを見ることができます。
エラーの場合はエラー内容も英語で表記されます。

また、「Sending」で検索することで、OBSからあなたのアプリに送信されたWebSocket通信ログを探すことができます。

デバッグの時に、必ず役に立ちます。

自作プログラムから通信を開始する時のURL

OBSが実行されているPCと、自分のアプリが同一のPCで動く場合、

ws://127.0.0.1:4455

で接続できます。
4455は、WebSocketサーバーの設定で設定したポート番号です。
自分のやり方が悪いのか、wss:では動作確認が取れなかった。


OBSとWebSocketで接続後にする事

OBSに対してWebSocketで接続すると、一発目ですぐにOBS側から次のようなJSONデータが必ず飛んできます。(パスワードの認証なしの場合)

{“d”:{“obsWebSocketVersion”:”5.5.2″,”rpcVersion”:1},”op”:0}
(↑このデータをリファレンスではHelloと名付けている。)

これを受け取ったら、すぐにコチラから

{“d”: {“eventSubscriptions”: 100000,”rpcVersion”: 1},”op”: 1}

と、JSONデータを送信しましょう。(パスワードの認証なしの場合)
これを送ることでOBSとのやりとりが可能になるようです。

“d”というのはメインのデータですよ!という意味であり、OBSとの通信の決まり事なので固定だと思っていて良いです。
そして、obsのWebSocketのVersionが送られてきて、rcpVersionが1というデータが送られてくる。
一見1は固定のように思えるが、将来バージョンがあがるかもしれないので、送信する時のrcpVersionは、受信したrcpVersionをそのまま返してあげるのが良さそうだ。

eventSubscriptionsはリファレンスを見ても良くわからなかった。リファレンスでは33が挿入されていたが、適当に100000でも動きました。

受信のop:0や、送信のop:1は、通信の内容のカテゴリみたいなもので、公式リファレンスによると1から9まである。
OPはメッセージタイプと呼ばれるものらしい。
OP:0は接続後、最初にOBS側から送られてくるデータ、OP:1はOP:0を受け取った後に、こちらからOBSへ送信するデータ、OP:5はOBS側で何かイベントが起こったら自動で送信されてくるもの、OP:6は自作プログラムからOBSへなにかを要求する為のデータなど、その送信データが何を意味するデータなのかのカテゴリわけみたいなものだとリファレンスをみて思った。

結局やりたことは自作PGからOBSを動かしたいわけだからOP:6は使うことが多いだろう。


op:1のデータを送信する際のハイパー注意点

接続後、はじめて受信したデータに対して、上述したop:1のデータを送るのですが、この送信データを誤って2回以上送信すると、エラーで強制的にOBS側からWebSocketを切断されます。
ログファイルを見ると、2回目を送信した段階で、「すでにあなたは認証済です」と記載されていて、WebSocketが強制切断されていました。そういう仕様のようなので、2回以上送らないようにしましょう。

こちらから切断して、再接続する場合は問題なし。1度切断し、次に再接続した時に送信する場合は問題ありません。
上の注意点は、同一セッション内で2回以上送った場合の話です。


OBSのソース内にある動画をプログラムから再生させたかったのでやってみた

上述したop:1のJSONデータを送信したあと、

{“d”:{“negotiatedRpcVersion”:1},”op”:2}
という、opが2のデータがOBSからこちらのアプリケーションへJSONデータで飛んできます。

上のop:2のデータを受信した後に、

{“d”:{“requestData”:{“inputName”:”いらっしゃいませ動画”,”mediaAction”:”OBS_WEBSOCKET_MEDIA_INPUT_ACTION_RESTART”},”requestId”: {“id”: “takahashi”},”requestType”: “TriggerMediaInputAction”},”op”: 6}”

を送信したら、見事OBSのソース内の動画を再生できた。(下図参照)
“d”と”requestData”は、もはやOBSに動画を再生してくれと要求するので固定項目でしょう。
op:6は、リクエストデータなので6にする。
inputNameにOBSのソース内にある再生させたい動画のソース名を入れる。
mediaActionは、”OBS_WEBSOCKET_MEDIA_INPUT_ACTION_RESTART”を設定していますが、はじめmediaActionに入れる値が分からず、数時間ハマったうえ、githubのprotocol.jsonの中身をみて、試しに”OBS_WEBSOCKET_MEDIA_INPUT_ACTION_RESTART”を入れてみて、たまたまうまくいってしまった次第です。

requestIdの”id”は、何入れても動く模様で、ここでは”takahashi”と入れたが、試しに”はなもげら”と全角文字を入れても問題なく動作した。
返信メッセージと対になるようなので、送信(要求)に対して、obs側から返答があった時のメッセージ内のIDが同じなら送信に対しての返信のメッセージだよということが分かる。
したがって、”r1″、”r2″など、要求1回ごとに数値を増やして、要求ごとにidを別にするのが良いようです。
私は、要求回数が少ないので、はなもげらで使ってますが。

op:1のデータをOBSへ送信した後の注意点

op:1を送信した後、op:2を受け取るまでは、こちらから要求を出してはいけません。
必ずop:2を受け取った後に、OBSへの要求を出しましょう。

op:1のデータを送信した後、OBSからop:2のデータを貰う前に、こちらから要求を出すとエラーになり、op:2を受信する前に出した要求はエラーとなり実行されません。

必ずop:2を受信したことを確認してから、こちらからやりたい要求を出すようにコーディングしないとなりません。


同様にop:6を送信するとop:7が返ってきます。
複数の要求を連続で出す場合、OBSからのレスポンスを受けてから、次の要求を出しましょう。


おわりに

この記事がちょっとでもコーディングの参考になったら幸いです。



タイトルとURLをコピーしました