/* Copyright (c) 2019-present Evereal. All rights reserved. */ using System; using System.Linq; using System.Diagnostics; using System.IO; using UnityEngine; using Debug = UnityEngine.Debug; namespace Evereal.VideoCapture { public class Utils { private static System.Random random = new System.Random(); /// /// Save render texture to PNG image file. /// /// RenderTexture. /// File name. public static void RenderTextureToPNG(RenderTexture rtex, string fileName) { Texture2D tex = new Texture2D(rtex.width, rtex.height, TextureFormat.RGB24, false); RenderTexture.active = rtex; tex.ReadPixels(new Rect(0, 0, rtex.width, rtex.height), 0, 0, false); RenderTexture.active = null; TextureToPNG(tex, fileName); } /// /// Save texture to PNG image file. /// /// Tex. /// File name. public static void TextureToPNG(Texture2D tex, string fileName) { string filePath = "Captures/" + fileName; byte[] imageBytes = tex.EncodeToPNG(); System.IO.File.WriteAllBytes(filePath, imageBytes); Debug.Log("Save texture " + filePath); } /// /// Save render texture to JPG image file. /// /// RenderTexture. /// File name. public static void RenderTextureToJPG(RenderTexture rtex, string fileName) { Texture2D tex = new Texture2D(rtex.width, rtex.height, TextureFormat.RGB24, false); RenderTexture.active = rtex; tex.ReadPixels(new Rect(0, 0, rtex.width, rtex.height), 0, 0, false); RenderTexture.active = null; TextureToJPG(tex, fileName); } /// /// Save texture to JPG image file. /// /// Tex. /// File name. public static void TextureToJPG(Texture2D tex, string fileName) { string filePath = "Captures/" + fileName; byte[] imageBytes = tex.EncodeToJPG(); System.IO.File.WriteAllBytes(filePath, imageBytes); Debug.Log("Save texture " + filePath); } /// /// Create materials which will be used for equirect and cubemap generation. /// /// shader name /// material /// public static Material CreateMaterial(string sName, Material m2Create) { if (m2Create && (m2Create.shader.name == sName)) return m2Create; Shader s = Shader.Find(sName); return CreateMaterial(s, m2Create); } /// /// Create materials which will be used for equirect and cubemap generation. /// /// shader code /// material /// public static Material CreateMaterial(Shader s, Material m2Create) { if (!s) { Debug.Log("Create material missing shader!"); return null; } if (m2Create && (m2Create.shader == s) && (s.isSupported)) return m2Create; if (!s.isSupported) { return null; } if (m2Create != null) { UnityEngine.Object.Destroy(m2Create); } m2Create = new Material(s); m2Create.hideFlags = HideFlags.DontSave; return m2Create; } /// /// Create RenderTexture. /// /// /// /// /// /// /// /// public static RenderTexture CreateRenderTexture(int width, int height, int depth, int antiAliasing, RenderTexture t2Create, bool create = true) { if (t2Create && (t2Create.width == width) && (t2Create.height == height) && (t2Create.depth == depth) && (t2Create.antiAliasing == antiAliasing) && (t2Create.IsCreated() == create)) return t2Create; if (t2Create != null) { UnityEngine.Object.Destroy(t2Create); } t2Create = new RenderTexture(width, height, depth, RenderTextureFormat.ARGB32); //t2Create = new RenderTexture(width, height, depth, RenderTextureFormat.Default); t2Create.antiAliasing = antiAliasing; t2Create.hideFlags = HideFlags.HideAndDontSave; // Make sure render texture is created. if (create) t2Create.Create(); return t2Create; } /// /// Create Cubemap. /// /// /// /// public static Cubemap CreateCubemap(int cubemapSize, Cubemap c2Create) { if (c2Create && c2Create.width == cubemapSize) return c2Create; if (c2Create != null) { UnityEngine.Object.Destroy(c2Create); } c2Create = new Cubemap(cubemapSize, TextureFormat.RGB24, false); return c2Create; } /// /// Create Texture2D. /// /// /// /// /// public static Texture2D CreateTexture(int width, int height, Texture2D t2Create) { if (t2Create && (t2Create.width == width) && (t2Create.height == height)) return t2Create; if (t2Create != null) { UnityEngine.Object.Destroy(t2Create); } t2Create = new Texture2D(width, height, TextureFormat.RGBA32, false); t2Create.hideFlags = HideFlags.HideAndDontSave; return t2Create; } /// /// Generate random string. /// /// random string length /// public static string GetRandomString(int length) { const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; return new string(Enumerable.Repeat(chars, length) .Select(s => s[random.Next(s.Length)]).ToArray()); } public static string GetTimeString() { return DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss"); } public static string GetTimestampString() { return DateTime.Now.ToString("yyyyMMddHHmmssff"); } public static int GetClosestEvenNumber(int n) { if (n % 2 == 1) return n - 1; return n; } public static bool isWindows64Bit() { #if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN string sysInfo = SystemInfo.operatingSystem; return sysInfo.Substring(sysInfo.Length - 5).Equals("64bit"); #else return false; #endif } public static void EncodeVideo4K(string videoFile) { if (string.IsNullOrEmpty(videoFile)) { return; } if (!System.IO.File.Exists(videoFile)) { Debug.LogWarning("Video file " + videoFile + " is not found"); return; } Debug.Log("Start encode video " + videoFile + " to 4K"); string ext = System.IO.Path.GetExtension(videoFile); Process.Start(FFmpeg.path, " -i \"" + videoFile + "\" -s 4096x2160 \"" + videoFile.Replace(ext, "_4K" + ext) + "\""); } public static void EncodeVideo8K(string videoFile) { if (string.IsNullOrEmpty(videoFile)) { return; } if (!System.IO.File.Exists(videoFile)) { Debug.LogWarning("Video file " + videoFile + " is not found"); return; } Debug.Log("Start encode video " + videoFile + " to 8K"); string ext = System.IO.Path.GetExtension(videoFile); Process.Start(FFmpeg.path, " -i \"" + videoFile + "\" -s 7680x4320 \"" + videoFile.Replace(ext, "_8K" + ext) + "\""); } public static void ConvertVideoWmv(string videoFile) { if (string.IsNullOrEmpty(videoFile)) { return; } if (!System.IO.File.Exists(videoFile)) { Debug.LogWarning("Video file " + videoFile + " is not found"); return; } Debug.Log("Start convert video " + videoFile + " to WMV"); string ext = System.IO.Path.GetExtension(videoFile); Process.Start(FFmpeg.path, " -i \"" + videoFile + "\" -qscale 2 -vcodec msmpeg4 -acodec wmav2 \"" + videoFile.Replace(ext, ".wmv") + "\""); } public static void ConvertVideoAvi(string videoFile) { if (string.IsNullOrEmpty(videoFile)) { return; } if (!System.IO.File.Exists(videoFile)) { Debug.LogWarning("Video file " + videoFile + " is not found"); return; } Debug.Log("Start convert video " + videoFile + " to AVI"); string ext = System.IO.Path.GetExtension(videoFile); Process.Start(FFmpeg.path, " -i \"" + videoFile + "\" -vcodec copy -acodec copy \"" + videoFile.Replace(ext, ".avi") + "\""); } public static void ConvertVideoFlv(string videoFile) { if (string.IsNullOrEmpty(videoFile)) { return; } if (!System.IO.File.Exists(videoFile)) { Debug.LogWarning("Video file " + videoFile + " is not found"); return; } Debug.Log("Start convert video " + videoFile + " to FLV"); string ext = System.IO.Path.GetExtension(videoFile); Process.Start(FFmpeg.path, " -i \"" + videoFile + "\" -c:v libx264 -crf 19 \"" + videoFile.Replace(ext, ".flv") + "\""); } public static void ConvertVideoMkv(string videoFile) { if (string.IsNullOrEmpty(videoFile)) { return; } if (!System.IO.File.Exists(videoFile)) { Debug.LogWarning("Video file " + videoFile + " is not found"); return; } Debug.Log("Start convert video " + videoFile + " to MKV"); string ext = System.IO.Path.GetExtension(videoFile); Process.Start(FFmpeg.path, " -i \"" + videoFile + "\" -vcodec copy -acodec copy \"" + videoFile.Replace(ext, ".mkv") + "\""); } public static void ConvertVideoGif(string videoFile) { if (string.IsNullOrEmpty(videoFile)) { return; } if (!System.IO.File.Exists(videoFile)) { Debug.LogWarning("Video file " + videoFile + " is not found"); return; } Debug.Log("Start convert video " + videoFile + " to GIF"); string ext = System.IO.Path.GetExtension(videoFile); Process.Start(FFmpeg.path, " -i \"" + videoFile + "\" -s 1280x720 -pix_fmt rgb24 \"" + videoFile.Replace(ext, ".gif") + "\""); } public static string GetEncoderPresetExt(EncoderPreset preset) { switch (preset) { case EncoderPreset.H264_MP4: #if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN case EncoderPreset.H264_NVIDIA_MP4: #endif case EncoderPreset.H264_LOSSLESS_MP4: case EncoderPreset.H265_MP4: #if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN case EncoderPreset.H265_NVIDIA_MP4: #endif return "mp4"; case EncoderPreset.VP8_WEBM: case EncoderPreset.VP9_WEBM: return "webm"; case EncoderPreset.FFV1_MKV: return "mkv"; } return null; } public static string CreateFolder(string f2Create) { string folder = f2Create; if (string.IsNullOrEmpty(folder)) { folder = "Captures/"; } if (!folder.EndsWith("/") && !folder.EndsWith("\\")) { folder += "/"; } if (!Directory.Exists(folder)) { Directory.CreateDirectory(folder); } return Path.GetFullPath(folder); } public static void BrowseFolder(string folder) { if (string.IsNullOrEmpty(folder)) { folder = "Captures/"; } string fullPath = Path.GetFullPath(folder); if (Directory.Exists(fullPath)) { Process.Start(Path.GetFullPath(folder)); } else { Debug.LogWarning("Folder " + fullPath + " not existed!"); } } public static void WriteLogToDisk(string msg) { StreamWriter writer = new StreamWriter("UnityLog.txt", true); writer.WriteLine(msg); writer.Close(); } } }