0
0

obsws-pythonのテキスト編集で沼った話

Last updated at Posted at 2024-09-15

obsws-pythonとは

obsws-pythonとは、OBS StudioのWeb Socketを使って
プログラムから色々なOBS上の操作ができるライブラリです。

…と言っても当該ライブラリのGitHubを見てもいまいちわからなかった上に日本語の情報がかなり少なかったので非常に沼りました。
本記事では数ある機能の中でも主にテキストソースの編集にフォーカスして、私が確認できた内容を残そうと思います。

obsws-pythonは以下でインストール可能です。

pip install obsws-python

結果だけ知りたい方はGitHubに概要とコードサンプルを載せているのでこちらを参照ください。

経緯

今回私は別件の開発を行う過程でobsws-pythonを用いて
ただソースの表示/非表示をしたかったのですが、
「どうせならテキストの色とかも変えられたらいいよな…」
と思ったのが発端でした。

そこでテキストソースなどの設定編集に関わる
set_input_settingsを見てみたところ…

def set_input_settings(self, name, settings, overlay):
        """
        Sets the settings of an input.

        :param name: Name of the input to set the settings of
        :type name:  str
        :param settings: Object of settings to apply
        :type settings:  dict
        :param overlay: True == apply the settings on top of existing ones, False == reset the input to its defaults, then apply settings.
        :type overlay:  bool
        """

設定の変更に関わるのは上記のsettingsなのですが、
Object of settings to apply...?

いやその中身が知りたいんだよ!

ところが、どこを探してもその「適用する設定の対象」とやらの中身が
いまいちわかりませんでした。

解決…?

前置きが長くなりましたが、上記について私なりに色々調べてみた結果が以下のとおりです。

まずはobsws-pythonを以下のようにセットアップします。

import obsws-python as ws


password = 'OBS_WS_PASSWORD'
host = 'OBS_WS_HOST'
port = 'OBS_WS_PORT'

ws = ws.ReqClient(host=host, port=port, password=password)

これでOBS Studioとの基本的な連携は完了です。
各項目に入力する内容はYGPuzzleGTANT氏のこちらの記事がわかりやすいと思います。
続いて下記がテキストソースの設定変更についてです。

settings = {
            "font": {"size": 128, "face": "Arial"},
            "text": "test",
            "vertical": False,
            "color": 0,
            "opacity": 100,
            "gradient": False,
            "gradient_color": 0,
            "bk_color": 0,
            "bk_opacity": 0,
            "align": "right",
            "valign": "bottom",
            "outline": True,
            "outline_size": 5,
            "outline_color": 0,
            "outline_opacity": 0,
            }

        ws.set_input_settings(name=source_name,
                           settings=settings,
                           overlay=True)

各項目についてはこちらのREADME.mdで書いているので割愛します。

上記でテキストの編集に限っては大抵のことができると思いますが、
他にもソースの位置やクロップなどを設定できる項目もあります。
確認できた内容を全て載せると冗長になるので、
他の項目を更に調べたい方はOBS Studioで「ファイル」>「設定フォルダを表示」>「basic」>「scenes」よりscene_name.jsonから確認できます。
(このファイルにたどり着くまでが一番苦労しました)

しかしそれでもすべてを発見には至っていません。
日本語の情報が少ないライブラリだと思うので有識者の方に追加の知識求む…という感じです。

ちなみに発見した中でも曲者だったのがcolor関連の項目です。
#1A2B3Cみたいな感じでカラーコードを直接書き込むと予想していたのですが、
実際にはRGBをBGRに直し、10進数に変換したintで入力する必要がありました。
(例の場合だと、1A2B3C(16)3C2B1A(16)3943194(10))

上記の変換についても地味に面倒だったので、以下のコードを作りました。
カラーコードを入力すればOBS Studioに適した10進数を返してくれます。

def convert_to_decimal(hex_num: str) -> int:
    hex_num = hex_num
    decimal_num = int(hex_num, 16)

    return decimal_num


def reverse_by_pairs(hex_num):
    if hex_num[0] == "#":
        hex_num = hex_num[1:]

    pairs = [hex_num[i:i+2] for i in range(0, len(hex_num), 2)]
    reversed_pairs = pairs[::-1]

    return "".join(reversed_pairs)


if __name__ == "__main__":
    color_code = reverse_by_pairs(input("Please input the color code.\n"))
    result = convert_to_decimal(color_code)
    print(f"color code: {result}")

これにて、obsws-pythonを用いてOBS Studioのテキストソースの編集なら大抵のことはできるはずです。

総括

今回、set_input_settingssettingsの中身がわからず非常に苦戦しました。
私が見た限り日本語で情報があったものといえばテキスト内容の編集くらいだったので、私と同じように苦戦している方の助けになればという想いでまとめました。

変更可能な項目が多くまとめきれないのでObject of settings to applyと記載していたのかなと思いますが、それにしてもどこで設定項目の名称確認ができるかくらいはどこかに書いていてほしいですよね。
(書いていたのかもしれませんが)

今回のことは、いつか自分がライブラリを作ることがあったらユーザー視点も考えた設計にしようと思えたいい機会でした。
ライブラリのソースコードやGitHubのIssuesやDiscussionsなど、
情報の深い部分に潜って試行錯誤したり解決策を導く過程はいい勉強になったと思います。

ちなみにカラーコードの煩雑さは何かというところの憶測ですが、映像系(とまとめていいのかわかりませんが)ではBGRを採用することが多いようで、GUI的にはRGBのほうがわかりやすいからそちらを採用しつつ内部的にBGRに戻して10進数でデータを保管しているのかな、と思いました。

おまけ

最後におまけなんですけれども、皆さんお気づきでしょうか。
実はテキストの編集方法については上記で記載しましたが、
結局私の当初の目的だったソースの表示/非表示の方法については書いていません。
おまけでは上記についての簡単な説明を行います。

obsws-pythonを使ってソースの表示/非表示を切り替えるには
set_item_enabledを使って以下のように記述します。

ws.set_scene_item_enabled(scene_name=scene_name,
                       item_id=item_id,
                       enabled=True)

上記のenabled=Trueにすれば表示、Falseにすれば非表示になるのですが…
はい、わかります。
皆さんの気持ち、わかりますよ。

scene_nameはともかく、item_idってなんぞ

という感じですよね。

scene_nameは文字通りシーンの名前を入れるだけでいいのですが、item_idが若干曲者です。
これはなにかというと、OBSのソース上に並んでいる要素の上から順に0, 1, 2...みたいな単純なお話ではありません。
おそらくシーン内で作成されたソース順に1から振り分けられているようです。
ちなみにこれもscene_name.jsonで一応確認できます。
しかし、

「ソースを作成した順番なんて覚えていない!」
item_idscene_name.jsonから見つけるのは面倒!」

…という方の気持ちも大いに理解しています。
というか私がそうでした。

安心してください。
以下のコードでitem_idの一覧が取得できます。

output_source_id(scene_name):
        print("ID: sourceName")
        dicts = ws.get_scene_item_list(name=scene_name).scene_items
        
        for dict in dicts:
            print(f"{dict["sceneItemId"]}: {dict["sourceName"]}")

get_scene_item_listという機能を使って指定したシーン内のソースIDを確認することができます。
上記の出力例は以下のようになります。

ID: sourceName
1: text1
2: text2
3: image
4: bgm

はい、これでitem_idがわかりましたので
自由自在にソースの表示/非表示ができるはずです。
これにてOBS上で表示トランジションや非表示トランジションを設定することで
見栄えの良い(?)ソース操作が行えるようになると思います。

配信の開始やその他の情報の参照など、obsws-pythonでできることはたくさんあるようですし、
今のトランジション設定についてもプログラムから設定できると思いますが、
それはあくまでまた別のお話ということで、皆さんもぜひ活用してみてください。

今回公開しているコードの詳しい使い方や補足はGitHubに公開しています。
当記事での内容でわからないことがあればそちらもあわせてご参照ください。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0