Unity截屏调ffmpeg生成视频

Download FFmpeg for Windows

Unity 代码
using System.Diagnostics;
using System.IO;
using UnityEngine;
public class Test : MonoBehaviour
{private int width = 1280;private int height = 720;private Texture2D frame;private float fireRate = 0.04F;private float nextFire = 0.0F;RenderTexture rt;Rect rect;byte[] bytes;bool isReady = false;int index = 0;private string imagePath;private string ffmpegPath;private string videoPath;// Use this for initializationvoid Start(){Loom.Initialize();imagePath = @Application.streamingAssetsPath + "/Images/";ffmpegPath = @Application.streamingAssetsPath + "/ffmpeg/ffmpeg.exe";videoPath = @Application.streamingAssetsPath + "/test.mp4";if (!Directory.Exists(imagePath.TrimEnd('/'))) {Directory.CreateDirectory(imagePath.TrimEnd('/'));} rect = new Rect(0, 0, width, height);// 创建一个RenderTexture对象  rt = new RenderTexture(width, height, 0);frame = new Texture2D(width, height, TextureFormat.RGBA32, false);isReady = true;//CreatVideo();}// Update is called once per framevoid Update(){}private void FixedUpdate(){if (isReady && Time.time > nextFire){nextFire = Time.time + fireRate;CaptureCamera(Camera.main, index);index++;}}///   /// 对相机截图。   ///   /// The screenshot2.  /// Camera.要被截屏的相机  /// Rect.截屏的区域  void CaptureCamera(Camera camera, int index){// 临时设置相关相机的targetTexture为rt, 并手动渲染相关相机  camera.targetTexture = rt;camera.Render();//ps: --- 如果这样加上第二个相机,可以实现只截图某几个指定的相机一起看到的图像。  //ps: camera2.targetTexture = rt;  //ps: camera2.Render();  //ps: -------------------------------------------------------------------  // 激活这个rt, 并从中中读取像素。  RenderTexture.active = rt;frame.ReadPixels(rect, 0, 0);// 注:这个时候,它是从RenderTexture.active中读取像素  frame.Apply();// 重置相关参数,以使用camera继续在屏幕上显示  camera.targetTexture = null;//ps: camera2.targetTexture = null;  RenderTexture.active = null; // JC: added to avoid errors  最后将这些纹理数据,成一个png图片文件  bytes = frame.EncodeToJPG();Loom.RunAsync(() =>{//string filename = Application.dataPath + "/Screenshot.png";System.IO.File.WriteAllBytes(imagePath + index + ".jpg", bytes);//Debug.Log(string.Format("截屏了一张照片: {0}", filename));  });}private void OnApplicationQuit(){CreatVideo();}void CreatVideo(){Loom.RunAsync(() =>{//建立外部调用进程Process p = new Process();p.StartInfo.FileName = ffmpegPath;string args = "-f image2 -i " + imagePath + "%d.jpg -vcodec libx264 -r 25 " + videoPath;p.StartInfo.Arguments = args;p.StartInfo.UseShellExecute = false;//不使用操作系统外壳程序启动线程(一定为FALSE,详细的请看MSDN)p.StartInfo.RedirectStandardError = true;//把外部程序错误输出写到StandardError流中(这个一定要注意,FFMPEG的所有输出信息,都为错误输出流,用StandardOutput是捕获不到任何消息的...)p.StartInfo.CreateNoWindow = true;//不创建进程窗口p.ErrorDataReceived += new DataReceivedEventHandler(Output);//外部程序(这里是FFMPEG)输出流时候产生的事件,这里是把流的处理过程转移到下面的方法中,详细请查阅MSDNp.Start();//启动线程p.BeginErrorReadLine();//开始异步读取p.WaitForExit();//阻塞等待进程结束p.Close();//关闭进程p.Dispose();//释放资源DirectoryInfo dir = new DirectoryInfo(imagePath);dir.Delete(true);Directory.CreateDirectory(imagePath.TrimEnd('/'));});}private void Output(object sendProcess, DataReceivedEventArgs output){if (!string.IsNullOrEmpty(output.Data)){//处理方法...UnityEngine.Debug.Log(output.Data);}}
}

Win10x64,Unity5.6.2f1x64 点击这里下载工程 参考文章 http://www.cnblogs.com/tianma3798/p/6285602.html http://www.cnblogs.com/DHUtoBUAA/p/5551085.html 直接录制应用程序窗口,仅用于Windows程序和编辑器 2019.12.6
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using UnityEngine;/// 
/// 录制本程序窗口,仅用于Windows程序和编辑器
/// 
public class CaptureWindow : MonoBehaviour
{private string ffmpegPath;private string videoPath;private int processId;private Process process;// Use this for initializationvoid Start(){ffmpegPath = @Application.streamingAssetsPath + "/ffmpeg/ffmpeg.exe";videoPath = @Application.streamingAssetsPath + "/test.mp4";IntPtr handle = GetForegroundWindow();SetWindowText(handle.ToInt32(), Application.productName);}public void OnGUI(){if (GUILayout.Button("开始录制")){process = new Process();process.StartInfo.FileName = ffmpegPath;string args = " -f gdigrab -framerate 30 -i title=" + Application.productName + " -f mp4 " + videoPath;//string args = " -f gdigrab -framerate 30 -i desktop -f mp4 " + videoPath;process.StartInfo.Arguments = args;process.StartInfo.UseShellExecute = false;process.StartInfo.RedirectStandardError = true;process.StartInfo.RedirectStandardInput = true;process.StartInfo.RedirectStandardOutput = true;process.StartInfo.CreateNoWindow = true;process.ErrorDataReceived += new DataReceivedEventHandler(Output);process.Start();processId = process.Id;UnityEngine.Debug.Log("processId:" + processId);process.BeginErrorReadLine();//process.StandardInput.WriteLine("q");//process.WaitForExit(); }if (GUILayout.Button("停止录制")){if (process != null){process.StandardInput.WriteLine("q");process.WaitForExit();process.Close();process = null;}}}// Update is called once per framevoid Update(){}private void OnApplicationQuit(){if (process != null){process.StandardInput.WriteLine("q");process.WaitForExit();process.Close();//process.Kill();}}private void Output(object sendProcess, DataReceivedEventArgs output){if (!string.IsNullOrEmpty(output.Data)){ UnityEngine.Debug.Log(output.Data);}}#region /// /// 设置窗口名/// /// /// /// [DllImport("user32.dll", EntryPoint = "SetWindowText", CharSet = CharSet.Ansi)]public static extern int SetWindowText(int hwnd, string lpString);/// /// 获得本窗体的句柄  /// /// [DllImport("user32.dll")]public static extern IntPtr GetForegroundWindow();#endregion
}

 


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部