ElixirからWebSocketでOBSとやり取りするobs_websocket_exを作りました
録画・配信アプリケーションのOpen Broadcaster Software(OBS)は、WebSocketで外部から制御したり、OBS内のイベントを受け取ったりできます。しかし、ElixirからOBSを制御するライブラリは見当たらなかったので、obs_websocket_ex
というライブラリを作ってみました。
本記事では、使い方を簡単に紹介します。
obs_websocket_ex
の使い方
基本的な使い方
もっとも基本的な使い方は、以下の通りです。このスクリプトでは、WebSocketサーバの設定は認証を有効にしない状態を前提としています。
ハンドラとなるモジュールを定義し、use ObsWebSocket
した上で処理を書いていきます。
実行すると、以下の通りのデバッグログと、ハンドラーに渡されたメッセージが表示されます。
$ mix run ./examples/basic.exs
22:48:42.912 [debug] Hello (authentication not required): %{"obsWebSocketVersion" => "5.3.4", "rpcVersion" => 1}
Received Message - Type: :text -- Message: %{"d" => %{"negotiatedRpcVersion" => 1}, "op" => 2}
WebSocketに接続すると、Hello (OpCode 0)というメッセージが送信されてくるので、Identify (OpCode 1)というメッセージを送り返してやる必要があります。そのへんを、obs_websocket_ex
が自動的にやってくれています。
認証を有効にする
OBSのWebSocketサーバの設定で認証を有効にした場合は、以下のように書きます。先ほどのコードとの違いは、以下の通りです。
- ハンドラとなるモジュールの
start_link/2
関数呼び出し時に、パスワードをわたす - ハンドラとなるモジュールに、オプションとしてわたされたパスワードを取得するための
password/0
という関数を定義する
実行すると、以下の通りのデバッグログと、ハンドラーに渡されたメッセージが表示されます。
$ mix run ./examples/authentication.exs
22:55:51.013 [debug] Hello (authentication required): %{"authentication" => %{"challenge" => "jcja23BkFABk2l4nhzAPI/gSjGMiDqz5szLL6IZ2fiE=", "salt" => "GZVpXFCJANfNgEPs8H1P5PZIeZZGu+g0EqBikMcU3SA="}, "obsWebSocketVersion" => "5.3.4", "rpcVersion" => 1}
Received Message - Type: :text -- Message: %{"d" => %{"negotiatedRpcVersion" => 1}, "op" => 2}
さきほどと異なり、authentication
などのフィールドが増えています。このデータを用いて、Creating an authentication stringの説明に従い、認証に用いる情報をIdentify (OpCode 1)というメッセージで返してやる必要があります。
リクエストを送信する
接続がうまくいったら、なにかしら操作してみたいですよね。ここでは、よく使うであろうテキストの表示をしてみます。
まずは、テキスト欄を追加します。以下の画像の通り、message
という名前のテキスト欄を追加しましょう。
実行するコードは以下の通りです。
実行すると、以下の通りのデバッグログと、ハンドラーに渡されたメッセージが表示されます。
$ mix run .\examples\request.exs
23:06:12.152 [debug] Hello (authentication required): %{"authentication" => %{"challenge" => "7XkY0E1apBsH10Rf1rrzM0lW9WZB4kDDps/SpsGCpds=", "salt" => "GZVpXFCJANfNgEPs8H1P5PZIeZZGu+g0EqBikMcU3SA="}, "obsWebSocketVersion" => "5.3.4", "rpcVersion" => 1}
Received Message - Type: :text -- Message: %{"d" => %{"negotiatedRpcVersion" => 1}, "op" => 2}
Received Message - Type: :text -- Message: %{"d" => %{"requestId" => "43d37820-a0d3-11ee-9093-2cf05de4c937", "requestStatus" => %{"code" => 100, "result" => true}, "requestType" => "SetInputSettings"}, "op" => 7}
そして、以下の画像の通りmessage
という名前のテキスト欄にHello OBS!
と表示されています。
このコードの肝は、以下のリクエストを送信している箇所です。SetInputSettingsという名前のリクエストで、先ほど追加したテキスト欄の名前を指定しつつテキストを設定しています。
conn |> ObsWebSocket.request(:SetInputSettings, %{
inputName: "message",
inputSettings: %{text: "Hello OBS!"}
})
その他の例
その他の有用な例として、たとえばプログラムから録画や配信の開始・終了を制御したいということがありそうです。StartRecord
/ StopRecord
あるいはStartStreaming
/ StopStreaming
というリクエストを送信することで、それらの操作を行うことができます。
おわりに
ElixirからWebSocketでOBSとやり取りするobs_websocket_ex
の簡単な使い方を紹介しました。ElixirからもOBSを簡単にやりとりできるようになったので、ぜひお試しください。
Discussion