FFMPEG를 사용하여 성장하는 이미지 시퀀스에서 비디오 만들기

FFMPEG를 사용하여 성장하는 이미지 시퀀스에서 비디오 만들기

개인 3D 프로젝트를 이미지 시퀀스로 렌더링할 계획입니다. 각 프레임을 생성하고 이미지 파일로 저장하는 데 약 1분이 걸립니다.

렌더링이 완료되기 전에 일반 ffmpeg 구문을 사용하여 이 이미지 시퀀스를 비디오 파일( ffmpeg -i image-%03d.png output.mp4)로 변환하는 경우 마지막 이미지 파일에 도달하면 예상대로 중지됩니다. 그러나 이미지 파일 목록이 시간이 지남에 따라 증가함에 따라 이 구문을 사용하면 전체 항목을 비디오 파일로 변환하기 위해 프로젝트 렌더링이 완료될 때까지 기다려야 하므로 꽤 오랜 시간이 걸립니다.

ffmpeg를 허용하는 것이 가능한지 궁금합니다."기다리다"시퀀스의 다음 파일에 대해 그리고 "마지막 프레임"을 정의함으로써(또는 Ctrl+C를 사용하여 취소함으로써) 더 많은 파일에 대한 대기를 멈추고 비디오 파일을 완료한다는 것을 알 수 있습니까?

나는 이미지 파일과 외부 프로그램을 사용하여 생성되는 일종의 비디오 스트림을 입력으로 공급하는 것을 고려했지만 이것이 작동하는지와 일반적인 접근 방식이 확실하지 않습니다.

답변1

slhck 덕분에 파일이 생성될 때 ffmpeg의 stdin에 지속적으로 파일을 전달하는 C# 스크립트를 만들 수 있었습니다. 이 스크립트는 아무 키나 누르거나 지정된 끝 프레임에 도달하면 취소할 수 있습니다.

static void Main()
{
    //Async main method
    AsyncMain().GetAwaiter().GetResult();
}

static async Task AsyncMain()
{
    Console.WriteLine("Press any key to quit prematurely.");
    var maintask = RunFFMPEG();
    var readtask = Task.Run(() => Console.Read());
    await Task.WhenAny(maintask, readtask);
}

static async Task RunFFMPEG()
{
    await Task.Run(() =>
    {
        const int fps = 30;
        const string outfile = "out.mp4";
        const string args = "-y -framerate {0} -f image2pipe -i - -r {0} -c:v libx264 -movflags +faststart -pix_fmt yuv420p -crf 19 -preset veryslow {1}";
        const string dir = @"C:\testrender\";
        const string pattern = "{0}.png";
        const string path = dir + pattern;
        const int startNum = 0;
        const int endNum = 100;

        var pinf = new ProcessStartInfo("ffmpeg", string.Format(args, fps, outfile));
        pinf.UseShellExecute = false;
        pinf.RedirectStandardInput = true;
        pinf.WorkingDirectory = dir;

        Console.WriteLine("Starting ffmpeg...");
        var proc = Process.Start(pinf);
        using (var stream = new BinaryWriter(proc.StandardInput.BaseStream))
        {
            for (var i = startNum; i < endNum; i++)
            {
                //"D4" turns 5 to 0005 - change depending on pattern of input files
                var file = string.Format(path, i.ToString("D4"));
                System.Threading.SpinWait.SpinUntil(() => File.Exists(file) && CanReadFile(file));
                Console.WriteLine("Found file: " + file);
                stream.Write(File.ReadAllBytes(file));
            }
        }
        proc.WaitForExit();
        Console.WriteLine("Closed ffmpeg.");
    });



    bool CanReadFile(string file)
    {
        //Needs to be able to read file
        FileStream fs = null;
        try
        {
            fs = File.OpenRead(file);
            return true;
        }
        catch (IOException)
        {
            return false;
        }
        finally
        {
            if (fs != null)
                fs.Close();
        }
    }
}

이 형식은 TGA를 지원하지 않는 것 같지만 image2pipe예를 들어 PNG에서는 잘 작동합니다.

관련 정보