Unity利用截图保存图片并使用ffmpeg生成视频

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}");
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值