はじめに
RTSP配信された映像をUnityでストリーミングしたい場合があります。
しかし、Unityには標準でRTSP再生をサポートしているコンポーネントはありません。
今回はgujadot氏のRTSP_Unity_Pluginを用いてUnityにおいてRTSPストリーミングを導入する方法を解説します。
用いるソフトウェア
- Unity 2019.2.8f1
- Visual Studio 2017
- RTSP_Unity_Plugin
- FFmpeg
実装手順
DLL生成編
-
Visual StudioにVisual C++をインストールしておく。
-
FFmpegのダウンロードページにアクセスする。dev/shareの両方をダウンロード。
-
RTSP_Unity_Pluginをダウンロード。RTSPUnityPlugin.vcxproj(VC++ Project)をVisual Studioで開く。
-
作成したffmpeg以下にffmpeg/include、ffmpeg/libの2フォルダを作成する。
各フォルダに次の通り、ダウンロードしたFFmpegの内容をコピーする。ffmpeg/include <- copy <- FFmpeg/win64-dev/include
ffmpeg/lib <- copy <- FFmpeg/win64-dev/lib と FFmpeg/win64-shared/bin
-
Visual StudioのエクスプローラからRTSPUnityPluginのプロパティを開く。
-
[構成プロパティ]-[C/C++]-[全般] を開く。
-
[追加のインクルードディレクトリ]に以下を入力。
$(SolutionDir)\ffmpeg\include;%(AdditionalIncludeDirectories)
9. [追加の#usingディレクトリ]に以下を入力。
```
$(SolutionDir)\ffmpeg\lib
-
[構成プロパティ]-[リンカー]-[全般] を開く。
-
[追加のライブラリディレクトリ]に以下を入力。
$(SolutionDir)\ffmpeg\lib;%(AdditionalLibraryDirectories)
9. [構成プロパティ]-[デバッグ] を開く。
9. [コマンド]に以下を入力。
```
$(TargetPath)
-
[構成プロパティ]-[リンカー]-[入力] を開く。
-
[追加の依存ファイル]に以下を入力。
avcodec.lib
avdevice.lib
avfilter.lib
avformat.lib
avutil.lib
postproc.lib
swresample.lib
swscale.lib
11. [構成プロパティ]-[ビルドイベント]-[リンク前のイベント] を開く。
* [コマンドライン]に以下を入力。
```
copy "$(SolutionDir)ffmpeg\lib\avcodec-57.dll" "$(TargetDir)"
copy "$(SolutionDir)ffmpeg\lib\avdevice-57.dll" "$(TargetDir)"
copy "$(SolutionDir)ffmpeg\lib\avfilter-6.dll" "$(TargetDir)"
copy "$(SolutionDir)ffmpeg\lib\avformat-57.dll" "$(TargetDir)"
copy "$(SolutionDir)ffmpeg\lib\avutil-55.dll" "$(TargetDir)"
copy "$(SolutionDir)ffmpeg\lib\postproc-54.dll" "$(TargetDir)"
copy "$(SolutionDir)ffmpeg\lib\swresample-2.dll" "$(TargetDir)"
copy "$(SolutionDir)ffmpeg\lib\swscale-4.dll" "$(TargetDir)"
- ビルドする。
以上の手順を踏むと、build\x64\Release\RTSPUnityPlugin.dll
が生成されます。
Unity編
DLLの配置
上記の手順で生成されたReleaseフォルダをAssets/Plugins下に配置する。
オブジェクトへの適用
ストリームしたいマテリアルのオブジェクトに次のスクリプトをアタッチする。
(setRTSPTexture.cs)
using UnityEngine;
using System;
using System.Collections;
using System.Runtime.InteropServices;
public class SetRTSPTexture : MonoBehaviour {
[DllImport("RTSPUnityPlugin")]
private static extern void SetTimeFromUnity(float t);
[DllImport("RTSPUnityPlugin")]
private static extern IntPtr GetRenderEventFunc();
[DllImport("RTSPUnityPlugin")]
private static extern void SetTextureAsRTSPSink(string rtsp_uri,System.IntPtr texture, int h, int w);
public string g_rtspUri = "rtsp://localhost:8554/stream";
IEnumerator Start()
{
CreateTextureAndPassToPlugin();
yield return StartCoroutine("CallPluginAtEndOfFrames");
}
private void CreateTextureAndPassToPlugin()
{
// Create a texture
Texture2D tex = new Texture2D(256, 256, TextureFormat.RGBA32, false);
// Set point filtering just so we can see the pixels clearly
tex.filterMode = FilterMode.Point;
// Call Apply() so it's actually uploaded to the GPU
tex.Apply();
// Set texture onto our material
GetComponent<Renderer>().material.mainTexture = tex;
// Pass texture pointer to the plugin
SetTextureAsRTSPSink(g_rtspUri, tex.GetNativeTexturePtr(), tex.width, tex.height);
}
private IEnumerator CallPluginAtEndOfFrames()
{
while (true)
{
// Wait until all frame rendering is done
yield return new WaitForEndOfFrame();
// Set time for the plugin
SetTimeFromUnity(Time.timeSinceLevelLoad);
// Issue a plugin event with arbitrary integer identifier.
// The plugin can distinguish between different
// things it needs to do based on this ID.
// For our simple plugin, it does not matter which ID we pass here.
GL.IssuePluginEvent(GetRenderEventFunc(), 1);
}
}
}
これでUnityを実行すると、RTSPを受信してオブジェクトのテクスチャで再生されます。
最後に
このプラグインを用いればTHETAなどのネットワークカメラから映像をライブ配信できるので、Unityでビデオチャットのような面白い機能が実現できそうです。素晴らしいプラグインを提供してくださったgujadot氏に感謝!