配信画面に「今押してるキー」を出すアレ、OBSのプラグインや既存ツールで色々ありますが、
自分の構成(2PC配信+レバーレス)に合うものが意外と無く、結局自作しました。

OBSオーバーレイの表示例(キーボードモード)

iniwa/input-relay として公開しています。

なんで作ったのか

要件としてはこのあたり。

  • 2PC配信で Main PC の入力を Sub PC のOBSに出したい
  • SF6を遊ぶので レバーレスレイアウト が欲しい
  • 入力履歴(コマンドの履歴表示)も欲しい
  • キーボード/ゲームパッドをワンボタンで切り替えて使いたい
  • 1PC運用にも切り替えたい時がある

既存のツールだと「2PCに対応してない」「レバーレス表示が無い」「履歴と同時表示できない」「設定がXMLで辛い」みたいに、惜しいところで噛み合わず‥‥。
自分で作ってしまいました。

ざっくり構成

2つの動作モードがあります。

単独モード(1PC)

1台のPCで入力キャプチャ〜OBS表示まで完結するパターン。

PC (standalone)
└─ input_server.py --standalone
   ├─ 入力キャプチャ : keyboard / mouse / gamepad
   └─ HTTP server   : overlay.html (OBS Browser Source)

2PCモード(Main PC → Sub PC)

配信PCを別に立てている人向け。Main PC側の入力をWebSocketでSub PCに飛ばし、Sub PCのOBSがそのまま表示します。

2PC構成
├─ Main PC (sender)
│  └─ input_sender.py
│     ├─ 入力キャプチャ : keyboard / mouse / gamepad
│     └─ WebSocket送信 → Sub PC (LAN)
└─ Sub PC (receiver)
   └─ input_server.py
      ├─ WebSocket 受信
      └─ HTTP server : overlay.html (OBS Browser Source)

OBSはブラウザソースで http://<Receiver IP>:8081/overlay.html を読むだけ。
レイアウトは別ファイルに書いて読んでるので、OBSを再起動しなくても設定変更が反映されます。

できる事

機能 内容
キーボード表示 WASDなど任意のキー配置を表示。配置はGUIから編集可
レバーレス表示 方向ボタン4つ+アクションボタンを Hitbox 配置で描画
コントローラ表示 ゲームパッドのボタン配置
入力履歴 スト6の練習モードっぽいやつ。最大表示数とアイドルタイムアウト指定可
マウストレイル マウスの軌跡を残す。FPS配信向け
モード切替 F12キーまたは設定GUIから keyboard / leverless / controller を切替
リモコン Main PCのキーボード入力をSub PCに注入できる(後述)

各モードの表示例はこんな感じです。

セットアップ

単独モード

リポジトリをクローンして start_standalone.bat をダブルクリック。
依存パッケージのインストールとサーバー起動まで全部batがやってくれます。

コマンドラインなら下記。

python receiver/input_server.py --http-port 8081 --standalone

2PCモード

両方のPCにリポジトリをクローンして、

  • Sub PC: start_receiver.bat を起動(初回のみ管理者権限。ファイアウォールルールを足すため)
  • Main PC: start_sender.bat を起動

これだけで動きます。Sender が起動すると自動でReceiverに繋ぎにいきます。

OBSへの登録

  1. ソースに「ブラウザ」を追加
  2. URLに http://localhost:8081/overlay.html(2PCの場合は localhost をReceiver PCのIPに)
  3. 幅700 / 高さ200 くらい(適宜調整)
  4. カスタムCSSは空でOK

URL一覧

1つのサーバで複数のページを返してるので、用途で使い分けできます。

URL 内容
/ 設定GUI
/overlay.html キー表示 + 入力履歴(両方表示)
/input キー表示のみ
/history 入力履歴のみ
/mouse-trail マウストレイル

OBSのソースを分けたい時は /input/history を別々に追加すると好きな位置に置けます。

履歴とマウストレイルの表示はこんな感じ。

設定GUI(Sub PC)

ブラウザで http://localhost:8081/ を開くと設定画面が出ます。極力GUIで完結させました。

Sub PC 設定GUI(Sender タブ)
タブ 内容
Sender 接続先IP、ポート、モード切替キー
Keyboard 表示するキーの追加・削除・位置
Leverless 方向ボタン・アクションボタンのマッピング
Controller コントローラレイアウト
入力履歴 表示数・アイドルタイムアウト
マウス軌跡 マウストレイルの色・感度・表示時間
レイアウト調整 パネル位置と倍率
デバッグ 押されているキー/ボタンの生確認

ページ下部にリアルタイムプレビューを置いてあるので、調整しながら確認できます。
各タブの中身はこのへん(クリックで拡大)。

モード切替

  • F12 キーで手動切替(keyboardleverlesscontroller を循環)
  • 切替キーは設定GUIから変更可能
  • 設定GUIのボタンからもモード切替が可能

Sender側のGUI(Main PC)

Main PC で sender を起動すると、http://localhost:8082/ にちょっとした設定/状態確認用GUIも立ち上がります。

Sender PC のGUI

主にこのへんが触れます。

項目 内容
接続状態 Receiver との接続状態 / リモコンモードのON-OFF
接続設定 送信先ホスト・ポート
リモートオーバーレイ リモコン中に画面端へ出す「<対象PC名>を操作中」表示の設定
コントローラ選択 複数刺さっている時にどれを使うかをラジオボタンで切替
入力モニタ 選択中コントローラからの生入力をリアルタイム表示

Sub PC側のGUIほど触る場面はありませんが、コントローラの切替や入力確認、リモートオーバーレイの位置調整はここから。

リモコンモード(2PCのみ)

2PCモード限定で、Main PCのキーボード入力をSub PCに注入する機能を入れています。
Sub PCに置いてあるブラウザを操作するとか、配信ツールを直接いじりたいとかの時用。

Scroll Lock キーでON/OFF切替(GUIからもトグル可)。
リモコンON中はMain PCの画面端に「<対象PC名>を操作中」という半透明オーバーレイが出ます。
ゲームウィンドウからフォーカスを奪う事でMain PC側のゲームに入力が漏れないようにしてあります。

リモコンON中に表示されるオーバーレイ

キーボードのみで、マウスは対象外。Sub PC側にもマウスを別途用意する運用です(割り切った理由は後述)。

ハマったところ・割り切ったところ

キャプボ経由で入力表示だけ先行する

Input-Relay 自体はほぼ無遅延で動くんですが、配信視聴側からするとキャプボ経由のゲーム画面のほうに数フレーム遅延が乗っています。
何も対策しないと 入力オーバーレイだけが先に出てゲーム画面が後から動く という不自然な見え方になってしまうので、Input-Relay 側に「表示遅延」設定を入れて、ms単位でこちら側を意図的に遅延させてキャプボの絵と合わせる仕組みにしました。

コントローラを抜き差しすると認識が外れる

Main PC でコントローラを抜いたり挿し直したりすると、Sender が新しいデバイスを掴み直してくれない事がそこそこあります。
今のところ Sender プロセスを再起動するしか解決策が無く、Sender側GUIに「Sender を再起動」ボタンを置いてその場で叩けるようにしてしのいでいます。
pygame の joystick 検出周りの挙動な気がしていますが、根治には至らず‥‥。

マウスのリモコンは諦めた

キーボードと違って、マウスは Raw Input をバックグラウンドで掴むゲームに対しては、フォーカスを奪っただけでは入力が漏れます。これを止めようとすると低レベルフック+座標固定+移動量打ち消し‥‥のような実装に近づいていって、アンチチートに不正プログラムと判断されるリスク が読めなくなります。
BAN食らうと泣くに泣けないので、マウスはリモコン対象外 という割り切りに落ち着きました。Sub PC側にもマウスを置く運用です。

使ってみての所感

リモコンモードでキーボード1台にまとめられたのが想像以上に快適 で、これだけでも作った甲斐がありました。机の上に2セット並ぶの、地味にストレスだったので‥‥。

SF6を遊んでいるときに 画面上で自分の入力が見えるのもかなり良い です。特に「 入れ込み 連打などで次の行動を先行入力で仕込んでおく小テクニック 」みたいな細かいやつは、配信視聴者には何をやったか伝わりにくい部分なんですが、入力表示があると「いま入れ込んだな」が見て分かるようになります。自分で見返す用にも便利。

入力遅延は Input-Relay 単体ではほぼ感じない(ローカル処理+LAN内 WebSocket)ので、最終的な見え方の調整は前述の「表示遅延」設定でほぼ間に合っています。

ファイル構成

ざっと見るとこんな感じ。

input-relay/
├── start_standalone.bat   # 単独モード起動
├── start_sender.bat       # 2PC: Main PC起動
├── start_receiver.bat     # 2PC: Sub PC起動
├── config/
│   ├── config.json
│   ├── sender_config.json
│   ├── presets.json
│   └── layout_presets.json
├── sender/
│   ├── input_sender.py
│   └── sender_gui.html
├── receiver/
│   ├── input_server.py
│   ├── input_injector.py
│   ├── standalone_capture.py
│   ├── overlay.html
│   └── config_gui.html
└── startup/
    ├── setup_startup_sender.bat
    └── setup_startup_receiver.bat

設定ファイルは初回起動時に自動生成されるので、手で作る必要は基本ありません。

依存パッケージ

batファイルが自動でpipしてくれますが、参考までに。

モード パッケージ
単独モード websockets, pynput, (pygame:ゲームパッド使う場合)
2PC Sender websockets, pynput, pygame
2PC Receiver websockets のみ

Receiver側はPython本体+websocketsだけで済むので、Sub PCの環境を汚さず置けます。

外部からAPIを叩く

別ツールから設定変更したい都合で、設定/プリセットの取得・保存ができるJSON APIを生やしています。
receiver/ の HTTP サーバ(既定 8081)が下記を受け付けます。

  • GET /api/config / POST /api/configconfig.json 全体の取得・上書き
  • GET /api/presets 系 — プリセット読み書き
  • その他、状態取得用のエンドポイントいくつか

詳細は docs/api.md に置いてあります。
認証は無いのでLAN内専用 で使う前提です。外に晒さないように。

おわりに

あれもこれもと機能を盛り盛りにしてしまいましたが、自分の環境にぴったり合うものを作るとこうなりました。
SF6のレバーレス民、FPSのマウストレイル表示が欲しい人、2PC構成で入力表示を出したい人‥‥あたりに刺さればなぁと。

OBSのブラウザソースで完結する作りなので、レイアウトを自分でCSSいじって変えたい人にも触りやすいと思います。
バグ報告・要望はGitHub Issue からお願いします。

関連記事

2PC配信の環境を構築した ※公開後にリンク差し替え予定

参考