Created
December 2, 2017 06:56
-
-
Save takashicompany/e43bb27d114e71f998a0f7b6a10379d6 to your computer and use it in GitHub Desktop.
プレイヤーの画面とは別視点のリプレイを録画する
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
// UnityEngineと名前空間を分ける | |
using ocv = OpenCVForUnity; | |
// 録画に使いたいカメラにつけるコンポーネント | |
[RequireComponent(typeof(Camera))] | |
public class OffscreenCaptureManager : MonoBehaviour | |
{ | |
// 録画用のカメラが描画するテクスチャ | |
private RenderTexture _renderTexture; | |
// iOS端末以外で録画する際にRenderTextureから取得した画像を一旦Texture2Dに変換する | |
#if !(UNITY_IOS && !UNITY_EDITOR) | |
private Texture2D _convertTexture; | |
#endif | |
// 録画用のカメラの描画情報をOpenCV用のインスタンスに変更する | |
private ocv.Mat _mat; | |
// カメラから取得した描画情報を動画ファイルにするインスタンス | |
private ocv.VideoWriter _writer; | |
// 最後に録画した動画のファイルパス | |
private string _lastCapturedPath; | |
// 録画した動画を再生するプレイヤー | |
private UnityEngine.Video.VideoPlayer _player; | |
// 録画する動画の解像度。パフォーマンスにあわせて調整すると良い | |
private int _width = Screen.width; | |
private int _height = Screen.height; | |
// 初期化処理 | |
void Start() | |
{ | |
// 録画用のカメラにRenderTextureを設定する | |
_renderTexture = new RenderTexture(_width, _height, 24); | |
GetComponent<Camera>().targetTexture = _renderTexture; | |
// iOS端末以外ではRenderTexture → Texture2D → OpenCVForUnity.Matという順番で | |
// 変換する必要があるのでそれに使うインスタンスを生成 | |
#if !(UNITY_IOS && !UNITY_EDITOR) | |
_convertTexture = new Texture2D(_width, _height, TextureFormat.ARGB32, false); | |
#endif | |
_mat = new ocv.Mat(new ocv.Size(_width, _height), ocv.CvType.CV_8UC4); | |
// プレイヤーを生成 | |
_player = Camera.main.gameObject.AddComponent<UnityEngine.Video.VideoPlayer>(); | |
_player.playOnAwake = false; | |
_player.renderMode = UnityEngine.Video.VideoRenderMode.CameraNearPlane; | |
_player.enabled = false; | |
} | |
void OnDisable() | |
{ | |
EndCapture(); | |
} | |
// 録画を開始する関数 | |
void StartCapture() | |
{ | |
// 撮影中の場合、一旦撮影を停止する | |
EndCapture(); | |
// ファイルパスを生成。動作環境にあわせて拡張子を変えると吉 | |
var fileName = Application.temporaryCachePath + "/" + System.DateTime.Now.ToString("yyyyMMddHHmmss") + ".mov"; | |
// 動画生成インスタンスを初期化 | |
_writer = new ocv.VideoWriter( | |
fileName, | |
ocv.VideoWriter.fourcc('M', 'P', '4', 'V'), // 動作環境にあわせてコーデックを変えると吉 | |
30, | |
new ocv.Size(_width, _height), | |
true | |
); | |
// 録画した動画を後で再生できるようにファイルパスを保持 | |
_lastCapturedPath = fileName; | |
} | |
// 録画を終了する | |
void EndCapture() | |
{ | |
if (_writer != null) | |
{ | |
// 録画を停止する(動画ファイルが作成される) | |
_writer.release(); | |
_writer = null; | |
} | |
} | |
// 録画用のカメラの描画が終了したら動画ファイルに書き込む | |
void OnPostRender() | |
{ | |
if (_writer == null) | |
{ | |
return; | |
} | |
#if UNITY_IOS && !UNITY_EDITOR | |
// 描画情報をOpenCV用のインスタンスに流し込む | |
ocv.Utils.textureToMat(_renderTexture, _mat); | |
// 色情報を調整する | |
ocv.Imgproc.cvtColor(_mat, _mat, ocv.Imgproc.COLOR_BGR2BGRA); | |
// 動画ファイルに書き込み | |
_writer.write(_mat); | |
#else | |
// 描画情報を一度Texture2D型に流し込む | |
// 内部でTexture2D.ReadPixelsを呼んでいるので処理時間がかかります | |
ocv.Utils.textureToTexture2D(_renderTexture, _convertTexture); | |
// Texture2DをOpenCV用のインスタンスに流し込み | |
ocv.Utils.texture2DToMat(_convertTexture, _mat); | |
// 色情報を調整する | |
ocv.Imgproc.cvtColor(_mat, _mat, ocv.Imgproc.COLOR_RGB2BGR); | |
// 動画ファイルに書き込み | |
_writer.write(_mat); | |
#endif | |
} | |
// 最後に撮影した動画を再生する | |
void PlayVideo() | |
{ | |
if (string.IsNullOrEmpty(_lastCapturedPath)) | |
{ | |
return; | |
} | |
_player.url = _lastCapturedPath; | |
_player.enabled = true; | |
_player.Play(); | |
} | |
// 動画の再生を停止する | |
void StopVideo() | |
{ | |
_player.Stop(); | |
_player.enabled = false; | |
} | |
void OnGUI() | |
{ | |
if (GUI.Button(new Rect(0, 0, 100, 100), "fps:" + ((int)(1f / Time.deltaTime)).ToString())) | |
{ | |
} | |
if (GUI.Button(new Rect(0, 100, 100, 100), _writer == null ? "録画" : "終了")) | |
{ | |
if (_writer == null) | |
{ | |
StartCapture(); | |
} | |
else | |
{ | |
EndCapture(); | |
} | |
} | |
if (GUI.Button(new Rect(0, 200, 100, 100), _player.enabled ? "停止" : "再生")) | |
{ | |
if (_player.enabled) | |
{ | |
StopVideo(); | |
} | |
else | |
{ | |
PlayVideo(); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment