1. はじめに
UnityEditorで実行中にUSBカメラで録画する方法をまとめました.
無料/有料アセットありますが,今回はOpenCVSharpを使います.
VR用のシーン再生時にVR映像と現実の映像を同期して保存したいというのがモチベーションです.
なお,ビルド後使えるかは試していません.
2. 実行環境
- Windows 11 Pro
- Unity 2022.3.21f1
- Visual Studio 2022
- USB接続機器
- VIVE Pro Eye (HTC)
- キャプチャボード JVA06(j5create)
- USBカメラ C920(Logicool)
3. 手順
(1) NuGetForUnityダウンロード
この記事執筆地点ではバージョン4.2.0.
インストール手法は3種類あります.
unitypackageの場合はこちらからダウンロード↓
(2) import
ダウンロードしたunitypackageをインポート.
Assets>NuGet
フォルダとメニューにNuGetが追加されます.
(3) Nuget起動
メニューNuget > Manage NuGet Packages
をクリックするとパッケージ検索ウィンドウが出現します.
先人の記事を調べるにOpenCvSharp4.WindowsかOpenCvSharp4.runtime.winを使うパターンがあるみたいです.
runtimeの方は別途OpenCvSharpのzipを入手する必要があるみたい?
(4) OpenCVSharpインストール
今回はOpenCvSharp4.Windowsを使ってみます.
installボタンをぽちり.
Warningウィンドウがポップアップしますが,OKで大丈夫です.
![スクリーンショット 2025-02-03 192924.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F2654082%2Fd6c385eb-3f96-4a59-4cf2-875ab5db60f1.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=0a0914cdb8ff4ef701efff3d5ce97e92)
※dllをダウンロードしてAssets>Pluginsフォルダに入れるケースもヒットしましたが,Consoleにライブラリが二重で存在するみたいなエラーが出たので削除.(OpenCvShart4.runtime.winの場合は必要?)
一応手順を記すと,
- OpenCVホームページでバージョン4.10.0 (2024-06-03 Released)のWindowsインストーラをダウンロード
https://opencv.org/releases/ - pencv-4.10.0-windows.exe起動
- 出力されたopencvフォルダの
build>bin>opencv_videoio_ffmpeg4100_64.dll
をAssets>Pluginsにコピー
OpenCVSharpExtern.dllを特定のフォルダに入れる手順を踏むパターン[2][3][4]もあるみたいですが,やっていません.
(USBカメラで録画する分には問題なかったので)
とりあえず,これだけでUnityでPlayする分にはOpenCVSharpが使えます.
(4) USBカメラのデータを取得
USBカメラで録画し,aviファイルとして出力するスクリプトです.
VideoCapture()の引数のindexはHMDのカメラやFaceRigのような仮想カメラが入っている場合は0が使われているっぽいです.
0から探していって上手く映るのを探すといいと思います.
複数台カメラがある場合はPCに挿入した順序になるっぽいです.
using UnityEngine;
using OpenCvSharp;
using System.IO;
using System;
public class debug_OpenCvSharp : MonoBehaviour
{
private VideoCapture capture;
private VideoWriter writer;
private Mat frame;
private bool isRecording = false;
// cameraIndex 0: 何も写らない(HMD?) 1: j5craete(type-C) :2 USBカメラ
// NOTE: PCに接続した順番?
private int cameraIndex = 2;
private int frameWidth = 1920;
private int frameHeight = 1080;
private double fps = 60.0;
private string outputFilePath;
void Start()
{
// 接続されている機器を探す
for (int i = 0; i < 20; i++)
{
}
capture = new VideoCapture(cameraIndex);
if (!capture.IsOpened())
{
Debug.LogError("カメラを開けませんでした。");
return;
}
capture.Set(VideoCaptureProperties.FrameWidth, frameWidth);
capture.Set(VideoCaptureProperties.FrameHeight, frameHeight);
capture.Set(VideoCaptureProperties.Fps, fps);
frame = new Mat();
// desktopにoutput.aviというファイル名で保存
outputFilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "output.avi");
writer = new VideoWriter(outputFilePath, FourCC.MJPG, fps, new Size(frameWidth, frameHeight));
if (!writer.IsOpened())
{
Debug.LogError("VideoWriterの初期化に失敗しました。");
return;
} else
{
Debug.Log("VideoWriter is opened.");
}
}
void Update()
{
// Rキーで録画開始 Scene再生終了で録画終了
if (Input.GetKeyDown(KeyCode.R))
{
isRecording = true;
Debug.Log("録画開始: " + outputFilePath);
}
if (isRecording && capture.IsOpened())
{
capture.Read(frame);
if (!frame.Empty())
{
writer.Write(frame);
}
}
}
void OnApplicationQuit()
{
isRecording = false;
writer?.Release();
capture?.Release();
frame?.Dispose();
Debug.Log("録画終了");
}
}
4. おわりに
今回はすんなり導入できたので何か足りないのではないか,と逆に訝しんでいるところ...
ネットの海を漁る限りdllをアタッチするとか一手間加えているみたいなので,今後何か問題が起こったら追記します.
OpenCVに頼らない無課金の方法として,VideoKit (旧NatCam)[5]やOpenCV plus Unityアセット[6]というのもあるんだとか.
VideoKitはAPIキーを発行したりと面倒&後々課金制とかになったら嫌なのでダウンロードしてやめました.
OpenCV plus UnityはメンテナンスがないのとUnsafe Codeを許可しないといけないのが何とも言えないところ.
参考文献
[1] toRisouP, "NuGetForUnityを使うときの注意点メモ", Qiita
[2] システム創成2021 CIC担当チーム 引継ぎ資料, "OpenCVSharp",
[3] iwasiblog, "Unity + OpenCvSharp (4.5.3)",
[4] Fantastic Works, "UnityでOpenCVSharpを使う",
[5] mattun, "Unityでカメラロールにアクセスしてみる", Zenn,
[6] きつね, "Unity+OpenCVに挑戦してみた", Note,