using System.Collections; using System.Collections.Generic; using System.Diagnostics; using UnityEngine; using System.IO; public class RT3script : MonoBehaviour { public RenderTexture colorImage, depthImage; public string outputRTMP = "rtmp://your_monaserver_address/live/stream_key"; public string mp4name = "my_movie_depth_ffmpeg.mp4"; public Texture2D outputImage; public int targetFrameRate = 30; int frameCount = 0; private Process ffmpegProcess; private string outputMP4; // Start is called before the first frame update void Start() { // Define file path for movie outputMP4 = Path.Combine(Path.GetTempPath(), mp4name); UnityEngine.Debug.Log(outputMP4); if (File.Exists(outputMP4)) { File.Delete(outputMP4); } colorImage = new RenderTexture(256,256,16,RenderTextureFormat.ARGB32); depthImage = new RenderTexture(256,256,16,RenderTextureFormat.ARGB32); outputImage = new Texture2D(512,512, TextureFormat.RGBA32, false); Camera c = GetComponent(); c.targetTexture = colorImage; Camera depthCamera = new GameObject("DepthCamera").AddComponent(); depthCamera.CopyFrom(c); // depthCamera.transform.position = c.transform.position; // depthCamera.transform.rotation = c.transform.rotation; // depthCamera.fieldOfView = c.fieldOfView; // depthCamera.nearClipPlane = c.nearClipPlane; // depthCamera.farClipPlane = c.farClipPlane; // depthCamera.orthographic = c.orthographic; depthCamera.targetTexture = depthImage; depthCamera.clearFlags = CameraClearFlags.SolidColor; depthCamera.backgroundColor = Color.black; depthCamera.SetReplacementShader(Shader.Find("Custom/DepthOnly"), ""); // Initialize FFmpeg process StartFFmpeg(); } // Update is called once per frame void Update() { float expectedFrames = Time.timeSinceLevelLoad * targetFrameRate; if (frameCount < expectedFrames) { // Graphics.CopyTexture(colorImage, 0, 0, 0, 0, 256, 256, outputImage, 0, 0, 0, 0); // Graphics.CopyTexture(depthImage, 0, 0, 0, 0, 256, 256, outputImage, 0, 0, 256, 0); RenderTexture.active = colorImage; outputImage.ReadPixels(new Rect(0, 0, 256, 256), 0, 0); outputImage.Apply(); RenderTexture.active = depthImage; outputImage.ReadPixels(new Rect(0, 0, 256, 256), 256, 0); outputImage.Apply(); // Get the raw pixel data and write it to FFmpeg's input stream byte[] frameBytes = outputImage.GetRawTextureData(); ffmpegProcess.StandardInput.BaseStream.Write(frameBytes, 0, frameBytes.Length); ffmpegProcess.StandardInput.BaseStream.Flush(); frameCount += 1; } } void OnDestroy() { } private void OnApplicationQuit() { // Stop FFmpeg process when the application quits if (ffmpegProcess != null && !ffmpegProcess.HasExited) { ffmpegProcess.StandardInput.Close(); // ffmpegProcess.Kill(); ffmpegProcess.WaitForExit(); ffmpegProcess = null; UnityEngine.Debug.Log("FFmpeg process stopped (hopefully) "); } } private void StartFFmpeg() { // Setup FFmpeg process with arguments for RTMP streaming string ffmpegArgs = $"-y -f rawvideo -vcodec rawvideo -pix_fmt rgb24 -s {outputImage.width}x{outputImage.height} " + // $"-r {targetFrameRate} -i pipe:0 -c:v libx264 -preset ultrafast -tune zerolatency -pix_fmt yuv420p -f flv {outputRTMP}"; $"-r 30 -i pipe:0 -c:v libx264 -preset ultrafast -pix_fmt yuv420p \"{outputMP4}\""; ffmpegProcess = new Process(); ffmpegProcess.StartInfo.FileName = "F:\\ffmpeg-7.1-full_build\\bin\\ffmpeg.exe"; ffmpegProcess.StartInfo.Arguments = ffmpegArgs; ffmpegProcess.StartInfo.UseShellExecute = false; ffmpegProcess.StartInfo.RedirectStandardInput = true; ffmpegProcess.StartInfo.CreateNoWindow = true; ffmpegProcess.Start(); UnityEngine.Debug.Log("FFmpeg process started with arguments: " + ffmpegArgs); } }