1、安装 FFmpeg,并加到系统的 PATH 环境变量
2、
using UnityEngine;
using System.IO;
using System.Diagnostics;
using Debug = UnityEngine.Debug;
public class CrossPlatformRecorder : MonoBehaviour
{
public Camera captureCamera;
public int width ;
public int height ;
public int frameRate = 30;
public string outputFolder = "RecordingFrames";
public bool autoStartRecording = true;
private string framePath;
private int frameCount = 0;
private bool recording = false;
void Start()
{
Application.runInBackground = true;
Time.captureFramerate = frameRate;
framePath = Path.Combine(Application.dataPath, "..", outputFolder);
if (!Directory.Exists(framePath))
{
Directory.CreateDirectory(framePath);
}
else
{
ClearFolderContents(framePath);
}
if (autoStartRecording)
StartRecording();
}
void LateUpdate()
{
if (!recording) return;
RenderTexture rt = new RenderTexture(width, height, 24);
captureCamera.targetTexture = rt;
Texture2D screenShot = new Texture2D(width, height, TextureFormat.RGB24, false);
captureCamera.Render();
RenderTexture.active = rt;
screenShot.ReadPixels(new Rect(0, 0, width, height), 0, 0);
screenShot.Apply();
captureCamera.targetTexture = null;
RenderTexture.active = null;
Destroy(rt);
byte[] bytes = screenShot.EncodeToPNG();
string fileName = Path.Combine(framePath, $"frame_{frameCount:D04}.png");
File.WriteAllBytes(fileName, bytes);
frameCount++;
Destroy(screenShot);
}
public void StartRecording()
{
recording = true;
Debug.Log("Recording started.");
}
public void StopRecording()
{
recording = false;
Debug.Log($"Recording stopped. {frameCount} frames captured.");
}
private void OnDisable()
{
StopRecording();
ExportVideo();
}
public void ExportVideo()
{
string ffmpegPath = GetFFmpegPath();
//string args = $"-framerate {frameRate} -i \"{framePath}/frame_%04d.png\" -c:v libx264 -pix_fmt yuv420p \"{framePath}/output.mp4\"";
string args = $"-framerate {frameRate} -i \"{framePath}/frame_%04d.png\" -c:v gif \"{framePath}/output.gif\"";
ProcessStartInfo psi = new ProcessStartInfo
{
FileName = ffmpegPath,
Arguments = args,
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = true
};
Process ffmpeg = new Process();
ffmpeg.StartInfo = psi;
ffmpeg.Start();
ffmpeg.WaitForExit();
Debug.Log("Video exported to: " + Path.Combine(framePath, "output.gif"));
}
private string GetFFmpegPath()
{
#if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN
return "ffmpeg"; // Ensure ffmpeg is in system PATH or provide full path
#else
return "ffmpeg"; // Linux/Mac should already have ffmpeg in path
#endif
}
public void ClearFolderContents(string folderPath)
{
if (!Directory.Exists(folderPath))
{
Debug.LogWarning($"文件夹不存在:{folderPath}");
return;
}
// 删除所有文件
foreach (string file in Directory.GetFiles(folderPath))
{
try
{
File.Delete(file);
}
catch (IOException ex)
{
Debug.LogError($"删除文件失败:{file} - {ex.Message}");
}
}
// 删除所有子文件夹
foreach (string dir in Directory.GetDirectories(folderPath))
{
try
{
Directory.Delete(dir, true); // true 表示递归删除子目录
}
catch (IOException ex)
{
Debug.LogError($"删除子文件夹失败:{dir} - {ex.Message}");
}
}
Debug.Log($"已清空文件夹内容:{folderPath}");
}
}