自習室

こもります

TCPSpout + KlakSpout で Unity ソフト間動画転送

なにをやるのか

  • 複数のウェブカメラや動画を、同期したり切り替えたりしながら、ネットワーク内の複数のコンピュータに渡して再生したい
    • つまり VJ ソフトみたいなことしたい
  • Unity で自作したい
  • Windows

概念図は以下の様な感じ

f:id:AMANE:20170825131105p:plain

  • マルチソースの録画再生機 兼MIXERとして、左側のマシンがあり、そこから、複数のクライアントに動画を送り出します。
  • 複数のクライアントにどの映像をどのタイミングでどんな組み合わせで送るか、を左側のマシンで一括で管理します。
  • クライアント側は受け取った動画を使ってよしなにやります。たとえば、VR-HMD を使ったりします。

調査

Spout

Mac でのプロジェクションマッピングとか VJ の界隈で Syphon という規格で動画データを渡すことは以前から知っていたのですが、その Windows 版が Spout です。Syphon と互換性があり、相互に送受信することも出来るみたいです。これを使いたい。

keijiro/KlakSpout

github.com

keijiro さんのこれを使うと、Unity で手軽に Spout が利用出来ます。使い方は GitHub に充分に書かれているので省略。

異なるカメラに二つ三つと SpoutSender コンポーネントをつけていくと、複数の映像を送り出すことも可能です。この様子を図に表すと以下の感じ。

f:id:AMANE:20170826212625p:plain

ただし、このアセットだけだと、同一マシン内でのビデオデータ送受信しかできません。そこで次に続きます。

TCPSpout

techlife.sg

Spout を、LAN内でPCをまたいで利用可能にしてくれるのが TCPSpoutです。

  • Spout 準拠の映像出力を捕まえて送り出すサーバ
  • 別PCのサーバを見つけて映像を受け取り内部で Spout の映像として利用可能としてくれるクライアント

のセットで利用します。図に示すと以下の感じ。この図の中で青い四角で描いてあるところを、Unityの KlakSpout にすれば、今回狙っている構成のできあがりです。Bonjour を使って、IP等打たなくてもLAN内のサーバを自動検出してくれるのが素晴らしいです。

f:id:AMANE:20170826143050p:plain

開発

実際の利用法を見ていきましょう。

1. Sender スクリプトのアタッチ

送りたい映像を撮る Unity の Camera に、 SpoutSender スクリプトをアタッチする

f:id:AMANE:20170826144131j:plain

2. Sender の確認

1.でSenderのスクリプトをアタッチしたことで、 Window/Klak/Spout Sender List に、Sender の名前が表示されるので確認する。この名称は、Senderスクリプトをアタッチしたゲームオブジェクトの名称になる。

f:id:AMANE:20170826143755j:plain

3. TCPSpout サーバの立ち上げ

TCPSpoutServer.exe を起動して、Spout Sender List から、上記名称の Sender を選択する。ここではSenderとして上記 “MainCamera” を選択しています。

f:id:AMANE:20170826144608p:plain

ここから先は、映像を受ける側(クライアント)側の設定です

4. TCPSpout クライアント立ち上げ

TCPSpoutClient.exe を起動して、Server List から、対象のサーバを選択します。Bonjour が自動でサーバを検出してくれるのが本当に素晴らしいです。私の例では名称が “TCPSpout FLAUROS” となっていますが、これは、TCPSpout が決めた、“TCPSpout” + “サーバマシン名” という形式で命名されており、Server を立ち上げているPCに私が “FLAUROS” と名付けているのから来ています。

f:id:AMANE:20170826150103p:plain

5. Sender の確認

ここでTCPSpout がつないでくれたSenderが見えていることを確認しておきましょう。確認の仕方は Server 側でやったときと同じです。名称は、 “MainCamera” ではなく、ここでは 一個前で選んだ “TCPSpout FLAUROS” になります。

f:id:AMANE:20170826150212p:plain

6. Receiver スクリプトのアタッチ

受け取るためのオブジェクトを作って、SpoutReceiver スクリプトをアタッチします。Sender として、先ほど確認した名称を記入します。受け取ったテクスチャを書き込む RenderTexture または、直接書き込む Renderer もここで登録します。詳細は公式のドキュメントを参照ください。

f:id:AMANE:20170826150431p:plain

ここで映像を受け取った RenderTexture をよしなに活用出来るようになります。

複数ストリーム用意する

KlakSpout の SpoutSender を、Unity シーン内で複数用意したカメラにそれぞれアタッチすることで、複数の映像を送り出すことができます。その数に合わせて、TCPSpoutServer.exe を複数起動すれば、複数の映像を同時に TCP 上に送り出すことが可能です。

受け取り側も同様に、 TCPSpoutClient.exe を複数起動することで、複数の Server から送り出されている Spout 映像を受け取ることが出来ます。

この際に注意点が、 TCPSpout のクライアントがつける、Sender の名前が、 “TCPSpout” + “マシン名” + “ (n)” <nはサーバの起動数> となることです。例えば、上記の私の例で言うと、 “TCPSpout FLAUROS (2)” という名前で検出されます。あんまりイケてませんが、気をつければ実用上は問題無いでしょう。

所感

同じLAN内で有線で繋いで居ると、FullHD の動画でも結構安定して送れています。自分はウェブカムの分割兼配信機、のように使いたいのですが、遅延に関しては、TCPSpout による物より、ウェブカムそのもの撮影から表示までの遅延の方が大きいです。

それと、人によっては、サーバから出す映像をブロードキャスト/マルチキャスト したいと言う要望もあるかと思います。今回の TCPSpout を利用するケースだと対応出来ません。 サーバでカメラを必要数作って、 SpoutSender を必要個数アタッチすることで、ワークラウンド的には対処出来るかと思います。

いずれにせよなかなか便利なので、積極的に使っていきたいと思います。