はじめに
NDIの映像をUnreal Engine 4で受信する方法を記載。Windowsのみ検証した。
NDIについては、この記事などを参照すると良い。HDMIやSDIのケーブル伝送に比べてしまうと(たとえローカル内であっても)遅延が発生するものの、それが許容される場合であれば、映像のとりまわしが容易なぶん非常に役立ち様々なストレスから開放される。NDIはハードウェアさえ不要で、設定も比較的容易でまさにメシア。
自分自身はBlackmagic DeckLinkなどのキャプチャボードからのUE4へストリームメディアとしての取り込みを何度も試みたが全てくじかれた。Duo2、Quad Recoreder 4K、BlackMagic以外ではAverMedia製品などを試したが、これらすべてUE4(とくに4.25)で直接受信させることができなかった。
Blackmagic Decklinkについては、Blackmagic designから提供されるドライバー類を同梱した、Desktop Video SDKが、バージョン11.6において不具合があり、UE4では受信できないことが報告されている。しかし、11.5.1や11.7においてはこの問題がなくSDIでの映像受信ができる。(事後加筆)
以下インストール方法。
1. NDI SDK、Pluginのインストール
以下2つをダウンロードし、解凍後、インストーラを用いてインストールする。
-
NDI Tools :
- Runtimeや各種ユーティリティツールなどがインストールできる
- 同梱されている Test Patterns や Studio Monitor など便利なツールがたくさんありそれだけでも価値がある
-
NDI SDK for Unreal Engine :
- ドキュメントも同梱されており、この記事と同じような説明が記載されている
上記はTest Patternsからの配信をStudio Monitorで受信している。なお、NDIの配信固有の識別名は マシン名 (アプリ名)
のようになる。自分のマシン(DESKTOP-O6G5712)内でTest Patternsを配信した場合、DESKTOP-O6G5712 (Test Pattern)
という命名になった。
2. プロジェクトにPluginを配置して有効化
上記の NDI SDK for Unreal Engine がインストールされた場所の、 NDI SDK for Unreal Engine > NDIExamples > Plugins にある、NDIIOPlugin
がPluginとなるファイル群の実体。デフォルトのパスは、 C:\Program Files\NewTek\NDI SDK for Unreal Engine\NDIExamples\Plugins
となる。
この NDIIOPlugin
をそのまま、UE4の適用したいプロジェクトディレクトリ直下の Plugins
ディレクトリ(なければ作成)に、コピーして配置。その後、プロジェクトを立ち上げると、Pluginが有効化され、NDIに関するオブジェクトなどが利用できるようなる。
3. NDI用のMedia SourceとTextureを用意
NDI Media Receiver
と NDI Media Texture2D
をそれぞれコンテンツブラウザ内で作成、名前をつける。
NDI Media Receiver
の設定項目にある、Video Texture
に先程作成したNDI Media Texture2D
を設定する。
4. NDI Receiverコンポーネントを持つアクターもしくはプレーヤーを配置する
- アクター(
Actor Blueprint
)もしくはプレーヤー(Player Controller Blueprint
)を作成 -
NDI Receiver
コンポーネントを追加する -
NDI Receiver
コンポーネントのNDI Media Source
に先程作成した、NDI Media Receiver
を設定
NDI Receiver
を持つには、アクターかプレーヤーのどちらでも良いが見通しが良くなる方が吉。
なお余談だが、NDI Receiver
はNon-Scene Component
のC++ファイルであるが、上述のNDI Media Source
がPrivate変数となっており、BlueprintのDetailsパネル上からしかアクセスできないのが非常に不便。Blueprintノード上でセットしたり、Levelエディタから設定することができず、このブループリントをNDIソース毎に使い回すことができないからだ。これを解消するにはこのコンポーネントのヘッダファイル(NDIReceiverComponent.h
)を書き換えて再Buildする。このステップは任意。
private:
/** The NDI Media Receiver representing the configuration of the network source to receive audio, video, and
* metadata from */
UPROPERTY(EditDefaultsOnly, Category = "Properties",
META = (DisplayName = "NDI Media Source", AllowPrivateAccess = true))
UNDIMediaReceiver* NDIMediaSource = nullptr;
↓
public:
/** The NDI Media Receiver representing the configuration of the network source to receive audio, video, and
* metadata from */
UPROPERTY(EditAnywhere, Category = "Properties",
META = (DisplayName = "NDI Media Source", AllowPrivateAccess = true))
UNDIMediaReceiver* NDIMediaSource = nullptr;
5. 任意のBlueprintから、NetworkSourceを監視し、変更された際に受信を開始する
NDI Receiver
を参照できる任意のBlueprintにノードを配置していく
-
NDI Finder
コンポーネントを用意する -
Network Sourceを監視し、ネットワークが接続されたりするタイミングでNDIを受信するようにする(
NDI Finder
>Bind Event to On Network Source Changed
) -
Callbackとなるイベントに、NDI Finderを引数にとれるCustomEventを追加して用いる。ここでは事前に
OnNetworkChanged
というCustomEventをつくっておいている。 -
このCallbackイベントにて、ネットワーク内の配信の中から識別名(
DESKTOP-O6G5712 (Test Pattern)
のような)を使って、ほしい配信を検索し(NDI Finder
>Find Network Source By Name
)
NetworkSourceを監視しないで、いきなりFind Network Source By Name
してStart Receiver
を走らせてもPIEでは動くかもしれない。しかし、自分の環境ではコンパイルした実行ファイルにおいては、上記のようにNetworkSouceを監視して、変更の度にNDIを受信をする関数を呼ばないと、NDIを正常に受信することができなかった。(解決にすごく時間を溶かした…)
また、ここでは省略するが、ストリームが不要になった際に、NDI Receiver
のEnd Receiver
を呼んで、明示的に受信を終わらせたほうが良い。
6. NDI Media Texture2Dで受信を確認し、利用する
作成したNDI Media Texture2Dを確認すると、ただしく受信できていれば動画が確認できる。このTextureはMaterialなどで参照して自由に使える。Chromakeyをしてリアルタイムで切り抜きもできた。