using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.UI; using System.Collections; using System.Collections.Generic; using OpenCVForUnity.CoreModule; using OpenCVForUnity.VideoioModule; using OpenCVForUnity.ImgprocModule; using OpenCVForUnity.UnityUtils; namespace OpenCVForUnitySample { /// /// VideoWriter Example /// An example of saving a video file using the VideoWriter class. /// http://docs.opencv.org/3.2.0/dd/d43/tutorial_py_video_display.html /// public class VideoWriterExample : MonoBehaviour { /// /// The cube. /// public GameObject cube; /// /// The preview panel. /// public RawImage previewPanel; /// /// The rec button. /// public Button RecButton; /// /// The play button. /// public Button PlayButton; /// /// The save path input field. /// public InputField savePathInputField; /// /// The max frame count. /// const int maxframeCount = 300; /// /// The frame count. /// int frameCount; /// /// The videowriter. /// VideoWriter writer; /// /// The videocapture. /// VideoCapture capture; /// /// The screen capture. /// Texture2D screenCapture; /// /// The recording frame rgb mat. /// Mat recordingFrameRgbMat; /// /// The preview rgb mat. /// Mat previewRgbMat; /// /// The preview texture. /// Texture2D previrwTexture; /// /// Indicates whether videowriter is recording. /// bool isRecording; /// /// Indicates whether videocapture is playing. /// bool isPlaying; /// /// The save path. /// string savePath; // Use this for initialization void Start () { PlayButton.interactable = false; previewPanel.gameObject.SetActive (false); Initialize (); } private void Initialize () { Texture2D imgTexture = Resources.Load ("lena") as Texture2D; Mat imgMat = new Mat (imgTexture.height, imgTexture.width, CvType.CV_8UC4); Utils.texture2DToMat (imgTexture, imgMat); Texture2D texture = new Texture2D (imgMat.cols (), imgMat.rows (), TextureFormat.RGBA32, false); Utils.matToTexture2D (imgMat, texture); cube.GetComponent ().material.mainTexture = texture; } // Update is called once per frame void Update () { if (!isPlaying) { cube.transform.Rotate (new Vector3 (90, 90, 0) * Time.deltaTime, Space.Self); } if (isPlaying) { //Loop play if (capture.get (Videoio.CAP_PROP_POS_FRAMES) >= capture.get (Videoio.CAP_PROP_FRAME_COUNT)) capture.set (Videoio.CAP_PROP_POS_FRAMES, 0); if (capture.grab ()) { capture.retrieve (previewRgbMat, 0); Imgproc.rectangle (previewRgbMat, new Point (0, 0), new Point (previewRgbMat.cols (), previewRgbMat.rows ()), new Scalar (0, 0, 255), 3); Imgproc.cvtColor (previewRgbMat, previewRgbMat, Imgproc.COLOR_BGR2RGB); Utils.fastMatToTexture2D (previewRgbMat, previrwTexture); } } } void OnPostRender () { if (isRecording) { if (frameCount >= maxframeCount || recordingFrameRgbMat.width () != Screen.width || recordingFrameRgbMat.height () != Screen.height) { OnRecButtonClick (); return; } frameCount++; // Take screen shot. screenCapture.ReadPixels (new UnityEngine.Rect (0, 0, Screen.width, Screen.height), 0, 0); screenCapture.Apply (); Utils.texture2DToMat (screenCapture, recordingFrameRgbMat); Imgproc.cvtColor (recordingFrameRgbMat, recordingFrameRgbMat, Imgproc.COLOR_RGB2BGR); Imgproc.putText (recordingFrameRgbMat, frameCount.ToString (), new Point (recordingFrameRgbMat.cols () - 70, 30), Imgproc.FONT_HERSHEY_SIMPLEX, 1.0, new Scalar (255, 255, 255), 2, Imgproc.LINE_AA, false); Imgproc.putText (recordingFrameRgbMat, "SavePath:", new Point (5, recordingFrameRgbMat.rows () - 30), Imgproc.FONT_HERSHEY_SIMPLEX, 0.8, new Scalar (0, 0, 255), 2, Imgproc.LINE_AA, false); Imgproc.putText (recordingFrameRgbMat, savePath, new Point (5, recordingFrameRgbMat.rows () - 8), Imgproc.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar (255, 255, 255), 0, Imgproc.LINE_AA, false); writer.write (recordingFrameRgbMat); } } private void StartRecording (string savePath) { if (isRecording || isPlaying) return; this.savePath = savePath; writer = new VideoWriter (); writer.open (savePath, VideoWriter.fourcc ('M', 'J', 'P', 'G'), 30, new Size (Screen.width, Screen.height)); if (!writer.isOpened ()) { Debug.LogError ("writer.isOpened() false"); writer.release (); return; } screenCapture = new Texture2D (Screen.width, Screen.height, TextureFormat.RGB24, false); recordingFrameRgbMat = new Mat (Screen.height, Screen.width, CvType.CV_8UC3); frameCount = 0; isRecording = true; } private void StopRecording () { if (!isRecording || isPlaying) return; if (writer != null && !writer.IsDisposed) writer.release (); if (recordingFrameRgbMat != null && !recordingFrameRgbMat.IsDisposed) recordingFrameRgbMat.Dispose (); savePathInputField.text = savePath; isRecording = false; } private void PlayVideo (string filePath) { if (isPlaying || isRecording) return; capture = new VideoCapture (); capture.open (filePath); if (!capture.isOpened ()) { Debug.LogError ("capture.isOpened() is false. "); capture.release (); return; } Debug.Log ("CAP_PROP_FORMAT: " + capture.get (Videoio.CAP_PROP_FORMAT)); Debug.Log ("CAP_PROP_POS_MSEC: " + capture.get (Videoio.CAP_PROP_POS_MSEC)); Debug.Log ("CAP_PROP_POS_FRAMES: " + capture.get (Videoio.CAP_PROP_POS_FRAMES)); Debug.Log ("CAP_PROP_POS_AVI_RATIO: " + capture.get (Videoio.CAP_PROP_POS_AVI_RATIO)); Debug.Log ("CAP_PROP_FRAME_COUNT: " + capture.get (Videoio.CAP_PROP_FRAME_COUNT)); Debug.Log ("CAP_PROP_FPS: " + capture.get (Videoio.CAP_PROP_FPS)); Debug.Log ("CAP_PROP_FRAME_WIDTH: " + capture.get (Videoio.CAP_PROP_FRAME_WIDTH)); Debug.Log ("CAP_PROP_FRAME_HEIGHT: " + capture.get (Videoio.CAP_PROP_FRAME_HEIGHT)); double ext = capture.get (Videoio.CAP_PROP_FOURCC); Debug.Log ("CAP_PROP_FOURCC: " + (char)((int)ext & 0XFF) + (char)(((int)ext & 0XFF00) >> 8) + (char)(((int)ext & 0XFF0000) >> 16) + (char)(((int)ext & 0XFF000000) >> 24)); previewRgbMat = new Mat (); capture.grab (); capture.retrieve (previewRgbMat, 0); int frameWidth = previewRgbMat.cols (); int frameHeight = previewRgbMat.rows (); previrwTexture = new Texture2D (frameWidth, frameHeight, TextureFormat.RGB24, false); capture.set (Videoio.CAP_PROP_POS_FRAMES, 0); previewPanel.texture = previrwTexture; isPlaying = true; } private void StopVideo () { if (!isPlaying || isRecording) return; if (capture != null && !capture.IsDisposed) capture.release (); if (previewRgbMat != null && !previewRgbMat.IsDisposed) previewRgbMat.Dispose (); isPlaying = false; } /// /// Raises the destroy event. /// void OnDestroy () { StopRecording (); StopVideo (); } /// /// Raises the back button click event. /// public void OnBackButtonClick () { SceneManager.LoadScene ("OpenCVForUnityExample"); } /// /// Raises the rec button click event. /// public void OnRecButtonClick () { if (isRecording) { RecButton.GetComponentInChildren ().color = Color.black; StopRecording (); PlayButton.interactable = true; previewPanel.gameObject.SetActive (false); } else { RecButton.GetComponentInChildren ().color = Color.red; StartRecording (Application.persistentDataPath + "/VideoWriterExample_output.avi"); PlayButton.interactable = false; } } /// /// Raises the play button click event. /// public void OnPlayButtonClick () { if (isPlaying) { StopVideo (); PlayButton.GetComponentInChildren ().text = "Play"; RecButton.interactable = true; previewPanel.gameObject.SetActive (false); } else { if (string.IsNullOrEmpty (savePath)) return; PlayVideo (savePath); PlayButton.GetComponentInChildren ().text = "Stop"; RecButton.interactable = false; previewPanel.gameObject.SetActive (true); } } } }