Mokerの徒然日記2.0

技術系のことをつらつらと。情報に責任は負いません。

obs-websocket-pyの使い方ほか

はじめに

OBSをpythonから使いたいときは

  1. OBS側にwebsocket経由でAPIを叩けるようになるプラグインを追加
  2. Pythonからwebsocket通信を行う

というアプローチがある。

そして、websocket通信をラップするPythonライブラリとしては

  1. obs-websocket-pypython 2/3に対応してる古くからあるライブラリ
  2. obs-ws-rc:python3.5↑に対応してる、async / awaitを用いたライブラリ

がある。

今回取り上げるのは前者。後者の解説は日本語だと動画配信ソフト「OBS」をPythonで操るぞ~ - KAYAC engineers' blogとかを参照されたい。

導入

OBS側のプラグインここからインストーラーをダウンロードして実行するだけ。インストール先にはデフォルト通りOBSのインストールディレクトリを選択すればよい。インストール後、obsのメニューバー「ツール」からWebsocket Server Settingsを選ぶことで、ポート、パスワードを設定可能。

obs-websocket-pyのインストールは

pip install obs-websocket-py

だけ。

obs-websocket-py

全体としてはeventとrequestの2種類に分けられる。 送れるAPIの種類はobs-websocketの方のドキュメントを見るとよさそう。

request

まずサンプルとしてシーン名をすべて取得するコードを示す(公式のサンプルを一部改変)。

from obswebsocket import obsws, requests

host = "localhost"
port = 4444
password = "secret"

ws = obsws(host, port, password)
ws.connect()

scenes = ws.call(requests.GetSceneList())

if scenes.status:
    for s in scenes.getScenes():
        print(s["name"])

ws.disconnect()

call()は引数としてRequestオブジェクトを取り、レスポンスデータをのっけたRequestオブジェクトを返す。

Requestオブジェクトは、共通して次のフィールドを持つ(obswebsocket.base_classes.Baserequestsを継承しているため)。

  • name:API
  • datain:APIの実行結果。OBSからpythonスクリプトに送られるデータ。
  • dataout:APIのパラメータ。pythonスクリプトからOBSに送られるデータ。
  • status:APIの実行ステータス。Noneなら未実行、Trueなら成功、Falseなら失敗?

さらに実行結果を取得するための関数として、それぞれAPIに対応したメソッドを持っている。 メソッド名は"get"の後ろに上に書いたAPI一覧の"Response Items"表の"Name"列から、"-"を取り除いて各先頭を大文字に(PascalCaseに)したもの。 例えば上のサンプルコードで使ったGetSceneListで行くと、Name欄が「current-scene」と「scenes」となっているので、「getCurrentScene」と「getScenes」となる。

event

調べてるなう。

おまけ

このライブラリはgenerate_classes.pyというスクリプトを使って、requests.pyとevents.pyを生成してるっぽい。仕組みとしては大元のobs-websocket内にドキュメントとして存在するAPI一覧が書かれたjsonファイルをダウンロードしてきて、それをもとに生成してるみたい。確かにラッパーならそうしたほうが更新についていきやすいよね。こういうjsonファイルをちゃんと用意しておくのもOSSのシステムとしてうまいな、と思った。