Zenn
📹

THINKLETのリアルタイム映像をRTMPストリームとしてOBSに取り込むための技術

2025/01/29に公開
1

初めまして、Fairy DevicesにてTHINKLET上で動作するAndroidアプリケーション等の開発をしています、Tamaki Hidetsugu / Ralphと申します。

今回、ポケモンカードゲームの有志大会であるくろいまなざし杯さんにて、THINKLETにて撮影した手元視点を活用したライブ配信をおこないました。

以下の動画は、実際ライブ配信のアーカイブで、THINKLETを用いた手元視点の映像が使われている箇所から再生されます。

https://youtu.be/e1dd7kQwV7U?t=214

このように、プレイヤー自身にしか見えない手元の情報を配信することで、臨場感があるだけでなく、実際のプレイヤーの思考プロセスが明らかになることで、より良い配信が可能になっています。

この記事では、複数台のTHINKLETを用いたライブ配信を実現するための手法について紹介します。

THINKLETの機能

THINKLETはAndroidベースのOSを搭載したウェアラブルデバイスであり、Wi-Fiを用いたインターネット通信やカメラを用いたアプリを一般的なスマホ向けAndroidアプリと同じように開発することができます。

ただし、大きな違いとして画面やタッチディスプレイといった、Androidアプリであれば必ず使用するUIが搭載されていません。

そのように聞くと特殊に聞こえてしまいますが、開発環境やフレームワークは一般的なAndroidアプリ開発と同じであるため、実際に開発してみるとAndroidアプリをいつものように作っているだけになります。

つまり、THINKLETで動作するアプリの開発では、Androidアプリの開発知識や既存の様々なライブラリを生かして高速に開発することができます。

開発に関するより詳しい情報は、以下の開発者ポータルをご覧ください。

https://fairydevicesrd.github.io/thinklet.app.developer/

THINKLETをライブカメラ化する

くろいまなざし杯の配信は、一般的なYouTube Liveの配信と同様にOBSを利用して行われています。

OBSはストリーミング配信を行うためのソフトウェアであり、複数の映像ソースを組み合わせたシーンを作成したり、複数のシーンを切り替えることで手軽に高機能な配信環境を作ることができます。

https://obsproject.com/ja

今回は既にOBSが配信に使われている環境にTHINKLETを追加する形になるため、THINKLETからの映像をOBSに取り込むことが可能な形式でデータを送信する必要があります。

ウェブカメラであればUSB接続で映像キャプチャデバイスとして、ビデオカメラなどであればHDMI・SDI接続でキャプチャボードを使用してOBS上へと映像を取り込むのが一般的です。

THINKLETをOBSを起動したPCへとUSB接続し、カメラアプリを起動している画面をscrcpyなどを用いてキャプチャすることで有線による接続も可能です。
しかし、有線接続により装着時の違和感が少し増してしまうため、ゲームプレイへの影響を減らすことを考えると無線による映像の転送をおこなうのが一番適していると考えられます。

つまりは、インターネット(イントラネット)を経由して映像をOBSを起動しているPCへと送る必要があります。

そういった用途に向けて、THINKLETで撮影した映像をリアルタイム配信するためのアプリとしてSquid Runを開発しました。

https://github.com/FairyDevicesRD/thinklet.squid.run

このアプリを用いることで、THINKLETのカメラで撮影している映像をリアルタイムで任意のRTMPサーバーへと送信することができます。

RTMPは一般的にストリーミングに用いられる技術であり、YouTube Liveでのライブ配信にも使われています。

THINKLETからSquid Runを用いてカメラ映像をRTMPストリームとして送信し、その映像をOBSへ取り込むことを目指していきます。

Squid Runの導入

Squid Runはアプリストアへの掲載やapkファイルの配布をおこなっていないため、自分の手でアプリをビルドする必要があります。

ビルド自体は一般的なAndroidアプリと同じ流れですが、THINKLET用のライブラリの取得にGitHub Packagesへアクセスする必要があるため、事前にread:packagesが付与された個人用アクセストークンを発行します。

Squid Runのソースコードをcloneした上で、github.propertiesへアクセストークンを記載します。

$ git clone https://github.com/FairyDevicesRD/thinklet.squid.run.git
$ cd thinklet.squid.run
$ touch github.properties
$ echo "username=[GitHubのユーザー名]" >> github.properties
$ echo "token=[発行した個人用アクセストークンを発行]" >> github.properties

アプリ自体のビルドとインストールをおこないます。

$ ./gradlew :app:assembleDebug
$ adb install -g ./app/build/outputs/apk/debug/app-debug.apk

Android StudioやGradleの installDebug タスクを使用しても問題ありませんが、アプリの動作にカメラ・ストレージ・マイクの権限が必要なため、adbコマンドやscrcpyで操作するなどして権限を付与するようにしてください。

これでTHINKLETへSquid Runをインストールすることができました。

OBSへRTMPストリームを取り込む

残念ながらOBSでは直接RTMPストリームを映像ソースとして取り込むことはできません。

これは、OBS自体にはRTMPストリームを受け取る機能(RTMPサーバー)が搭載されていないためです。

そこでRMTPサーバーを設置して、そこにTHINKLETからの映像を送信し、その映像をOBSで取り込むことを目指します。

ここでは、配信するPCにRTMPサーバーを設置する方法として、 mediamtx を使用する方法を紹介します。

https://github.com/bluenviron/mediamtx

Installation の項目に従い、mediamtxをダウンロードして実行します。

すると、以下のようなURLでRTMPサーバーを建てることができます。

rtmp://[実行しているPCのIPアドレス]:1935/[ストリームキー]

次にOBS上での設定です。

mediamtxへと送信されたRTMPストリームをOBSへ取り込む方法はいくつかありますが、様々な方法を検証した結果、WebRTCとしてブラウザソースで取り込むのが一番ラグが少なく、再接続時の安定性が高いという結論になりました。

mediamtxは受信したストリームを別のプロトコルのストリームとして送信するハブのような機能も持っているため、RTMPとして受け取り、WebRTCとして配信することも可能となっています。

ポケモンカードゲームの配信では、2人のプレイヤーそれぞれにTHINKLETを装着し、2台のTHINKLETからの映像を区別して受け取る必要があります。これ以降二人のプレイヤーを座る位置に応じて左側、右側と区別します。

OBSのソースから ブラウザ を2つ追加し、それぞれ以下のURLを指定します。

左側のプレイヤー用
http://localhost:8889/left

右側のプレイヤー用
http://localhost:8889/right

以下の動画は、実際にTHINKLETを用いて画面左側のWebページを撮影(RTMPでストリーミング)し、画面右側に立ち上げているOBSでWebRTCとして取り込んだ様子です。

https://www.youtube.com/watch?v=3HCByLLStuQ

なんと、この方法を用いた時のラグは0.2~3秒ほどで、ほぼリアルタイムの映像をOBSへと取り込むことができます。

また、WebRTCを併用する便利な点として、配信をおこなうPC以外でも、以下のURLへとブラウザでアクセスすると撮影されている映像をリアルタイムで見れるという点です。

左側のプレイヤー用
http://[配信をおこなうPCのIPアドレス]:8889/left

右側のプレイヤー用
http://[配信をおこなうPCのIPアドレス]:8889/right

別のPCからも閲覧できることで、映像が正しく送信されているかをOBSを使用せず確認したり、試合開始前に「画角こんな感じに映っています!」と装着したプレイヤーへ紹介したりすることが可能になります。これにより、配信の監視体制の強化だけでなく、装着者へわかりやすく説明することができました。

アプリケーションの設定

最後に、THINKLET上でSquid Runを起動させるための設定を行います。

THINKLETは搭載されている3つのボタンに、それぞれどのアプリを起動するか・どのような引数で起動するか、キーコンフィグを指定することができます。

https://fairydevicesrd.github.io/thinklet.app.developer/docs/keyConfig/

キーコンフィグを用いてSquid Runを起動できるようにします。

今回の設定では、1台のTHINKLETで左右どちらの配信先も選べるようにします。

先ほどの通り、ポケモンカードゲームの配信においては、同時に2台のTHINKLETを用いて左右の2者の映像を正しいURLへと配信する必要があります。

左側用のTHINKLET、右側用のTHINKLETをそれぞれ準備してもいいですが、デバイスが万が一不調になった時に備えて、映像の配信先を左右どちらでも選べるようにしておき、その場で選べるようにしておいた方が良いでしょう。

Squid Runはアプリ起動時の引数で配信先となるRTMPサーバーなどを指定することが可能なため、キーコンフィグを用いて、THINKLETの2つのボタンにそれぞれ左側のモード・右側のモードでSquid Runを起動する設定を行います。

設定ファイルは以下のようになります。

{
  "key-config": [
  {
    "key-name": "left", // or "right"
    "key-event": "single-released",
    "key-action": {
    "action-type": "launch-app",
    "action-param": {
      "package-name": "ai.fd.thinklet.app.squid.run",
      "class-name": "ai.fd.thinklet.app.squid.run.MainActivity",
      "action-name": "android.intent.action.MAIN",
      "extras": [
      {
        "key-name": "streamUrl",
        "key-value": "rtmp://[mediamtxを起動しているPCのIPアドレス]:1935"
      },
      {
        "key-name": "streamKey",
        "key-value": "left" // or "right"
      },
      {
        "key-name": "longSide",
        "key-type": "int",
        "key-value": 1280
      },
      {
        "key-name": "shortSide",
        "key-type": "int",
        "key-value": 720
      },
      {
        "key-name": "videoBitrate",
        "key-type": "int",
        "key-value": 6144
      }
      ],
      "flags": [
      "FLAG_ACTIVITY_NEW_TASK",
      "FLAG_ACTIVITY_CLEAR_TASK"
      ]
    }
    }
  },
  /* トップの`key-name`とstreamKeyの`key-value`の left/right違いでもう一つ記述する */
  ]
}

[mediamtxを起動しているPCのIPアドレス]の部分は、OBSへRTMPストリームを取り込むの項目と同じように実際のIPアドレスへと置き換えてください。

設定ファイルを用意したら、THINKLET上の指定された場所にファイルを転送します。

$ adb push ./key_config.json /storage/emulated/0/Android/data/ai.fd.thinklet.app.launcher/files/

転送後、一度電源ボタンを押す(ランチャーを起動する)と設定が読み込まれます。

その状態で3つのボタンのうち先端に近い方のボタンを押すと左側用のカメラが起動し、先端から遠い方のボタンを押すと右側用のカメラが起動します。

アプリ起動後は、真ん中のボタンを押すことで配信開始、もう一度押すと配信停止となります。

イベント中の動き

Squid Runを動作させたままの状態では、常時カメラが起動している状態になるため消費電力も多くなります。

THINKLETのバッテリー容量だと連続で1時間強ほどSquid Runを動作させることができますが、1試合あたり40分程度の時間がかかるため1試合ごとに充電を行う必要があります。

このようなケースでは、合計4台のTHINKLETを2台ずつ使用して、1試合ごとに配信と充電で回しながら運用するとスムーズです。

試合前後のオペレーションとしては、

  1. 2台のTHINKLETを取り出し、片方は左側用、もう片方は右側用の設定でアプリを起動・配信を開始する
  2. 配信卓の選手の人に装着方法や注意点などを説明し、取り付けてもらう
  3. 画角を確認し、このように見えていますよという案内や、必要に応じて装着具合を調整する。
  4. 試合後にデバイスを回収し、電源OFFにして充電器へと繋げる

以上の工程を繰り返す形になります。

発展編: YouTube LiveへTHINKLETから直接配信する

発展というよりはSquid Runを一番シンプルに使う方法です。

今回はOBSへと映像を取り込むためにmediamtxなどと組み合わせた構成にしましたが、YouTube Liveへ直に配信する場合はSquid Runのみで完結させることができます。

その場合は key_config.json の指定を以下のように変更します。

  1. streamUrlkey-valuertmps://a.rtmp.youtube.com/live2 にする
  2. streamKeykey-value をYouTube Liveのストリームキーにする

おわりに

THINKLETとSquid Runを用いることで、非常に手軽にカメラ映像を転送することができます。

くろいまなざし杯さんからもトレーディングカードゲームの配信をどのように構築するかをまとめたブログ記事が掲載されているので、ぜひそちらもご覧ください!

https://note.com/sorawo69aogeba54/n/n430704380919

1
フェアリーデバイセズ公式

Discussion

ログインするとコメントできます