見出し画像

【Unity】KlakNDIを使ってみる

試してみたシリーズです。今回はKeijiro氏の「KlakNDI」を使ってネットワーク越しにUnityからカメラ映像を送ってみます。名前の通り、NDI形式で送るためNDIに対応している様々なアプリケーションにUnityの映像を送ったり、Unity側で映像を受け取ることができます。

環境

Unity 2019.4.5f1 / Windows 10

1. 準備

KlakNDIはSystem.Memoryをはじめとするいくつのライブラリに依存しているため、scoped registryとNuGetを利用して依存解決を行います。利用するUnityプロジェクトフォルダ内のPackages/manifest.jsonに以下の内容を記述してください。

{
  "scopedRegistries": [
    {
      "name": "Unity NuGet",
      "url": "https://unitynuget-registry.azurewebsites.net",
      "scopes": [ "org.nuget" ]
    }

  ],
  "dependencies": {
    "org.nuget.system.memory": "4.5.3",

    ...
manifest.jsonへの記述

KlakNDIのREADMEにはKeijiro氏のscoped registryを含めた記述がなされていますが、後述するKlakNDIのソースコードを一部変更する必要があるためここではNuGetのみを追記します。

2. KlakNDIのインポート

Releaseページからソースコードをダウンロードします。

ソースコードのダウンロード

zipを展開したらフォルダ内の「jp.keijiro.klak.ndi」フォルダごとUnityエディタのProjectウィンドウにドラッグアンドドロップします。

コンソールログにエラーが出なければインポート完了です。

3. 設定

KlakNDIは映像ソースとしてGameView、Camera(URPとHDRPのみ)、Textureに対応しています。ビルトインレンダーパイプラインでカメラの映像を送りたい場合は、RenderTextureを経由して送ります。

まず、Projectウィンドウの右クリックから[Create] > [Render Texture]でRenderTextureを作成します。名前は「Camera 1」とします。

Render Textureの作成

作成したRenderTextureのインスペクタを開き、「Size」の値を表示したい解像度に設定します。ただし、ここの値はKlakNDIの仕様として16x8の倍数である必要があります。

解像度の設定

次にシーン上にある映像を送り出したいカメラのTarget Textureに、先程作成したRenderTextureをアタッチします。カメラが1台の場合や、全てのカメラのTargetTextureにRenderTextureを設定してしまうと、GameViewに何も映らなくなってしまうので、メインカメラとは別にNDI用のカメラを別途追加するのが良いでしょう。

TargetTextureにRenderTextureを設定

RenderTextureを設定したら、該当カメラのオブジェクトに対してAdd Componentから「NDI Sender」をアタッチします。

NDI Senderのアタッチ

NDI Senderの各値を以下のようにします。

  • NDI Name:Camera 1 (任意の値でOK。この名前を受信側で指定します)

  • Capture Method:Texture

  • Source Texture:カメラに設定したRenderTexture

NDI Senderの設定

すでにこの状態で映像は送信されているのですが、ビルドではうまく動作するものの、エディタ上ではOnValidateのタイミングとNDI Nameの更新がうまく反映されないため、jp.keijiro.klak.ndi@2.0.2\Runtime\Component\NdiSender_Properties.csのソースコードを以下のように変更します。(エディタでもAwakeで実行されるようにする)

変更前

    #if UNITY_EDITOR
    void OnValidate()
    #else
    void Awake()
    #endif
    {
        ndiName = _ndiName;
        captureMethod = _captureMethod;
        sourceCamera = _sourceCamera;
    }

変更後

    // #if UNITY_EDITOR
    // void OnValidate()
    // #else
    void Awake()
    // #endif
    {
        ndiName = _ndiName;
        captureMethod = _captureMethod;
        sourceCamera = _sourceCamera;
    }

4. 実行確認

KlakNDIはNDIの受信も可能なため、受信用のプロジェクトを別途作成します。プロジェクトは送信側と同じ手順でKlakNDIをインポートしてください。簡単に確認する方法として

1. 送信側と同じ解像度でRenderTextureを作成
2. Unlitなマテリアルを作成してテクスチャに1のRenderTextureをアタッチ
3. シーン上にQuadを配置して2で作成したマテリアルをアタッチ
4. QuadオブジェクトにNDI Receiverコンポーネントをアタッチ
5. NDI Nameの[Select]から送信NDI Nameを選択(送信側は実行しておく)
6. Target Textureに1で作成したRenderTextureをアタッチ
7. 実行

NDI Receiverの設定

うまく動作していれば以下のようになります。
(ユニティちゃんライブステージ! -Candy Rock Star-を使用)
© Unity Technologies Japan/UCL

NDI信号の受信 © UTJ/UCL

OBSでもプラグインを用いればNDIを受信できるため、ワイプやマルチカメラスイッチング配信などの演出をしてみると楽しいかもしれません。

OBS上でのNDI受信  © UTJ/UCL

5. おわりに

KlakNDIを用いてUnity上でNDIの送受信を行えることが確認できました。(Keijiro氏に感謝!)

今では動画配信サービスが一般的になり、ネットワーク上で映像がやり取りされるようになりましたが、送信側つまりスタジオ側でのローカルネットワーク上での映像通信はまだまだポテンシャルを秘めている気がしています。

これからも色々な使われ方が出てくるのが楽しみですね!🌱

6. 参考


この記事が気に入ったらサポートをしてみませんか?