FFMpegCore icon indicating copy to clipboard operation
FFMpegCore copied to clipboard

Issue with frame rate argument (r) when joining images

Open coffeemkr0 opened this issue 2 years ago • 3 comments
trafficstars

When using the following FFMpegCore arguments, the output video is incorrect - does not show all images and is not the correct length. It looks like the output is 2 of 8 images and only last 2 seconds, but it's a little hard to tell as the images don't show for 1 second each and just sort of flash from one to another at the end of the video.

FFMpegArguments
                .FromFileInput(Path.Combine(workingFolder, $"%06d.png"), false)
                .OutputToFile(outputFile, true, options => options
                    .WithFramerate(1)
                    .ForcePixelFormat("yuv420p") )
                .NotifyOnError(Console.WriteLine)
                .ProcessSynchronously();

I wrote the start info arguments that FFMpegCore produced from the above arguments to the console and got this: -i "{some folder}\%06d.png" -r 1 -pix_fmt yuv420p "{some folder}\output.mp4" -y

Using ffmpeg directly, these arguments produce the correct result (with 8 images, it produces an 8 second video): -r 1 -i "{some folder}\%06d.png" -pix_fmt yuv420p "{some folder}\output.mp4" -y

It appears that just moving the framerate argument position produces the desired result, but I am not sure why.

coffeemkr0 avatar Aug 09 '23 00:08 coffeemkr0

According to Chat GPT, moving the -r parameter to be before the input file will end up specifying the frame rate for the input, signifying that each image is 1 frame per second.

Specifying it on the output file does something different.

I seem to get the same sort of output when using the FFMpeg helper: FFMpeg.JoinImageSequence(outputFile, frameRate: 1, Directory.GetFiles(workingFolder)); This produces the same video as the arguments in my first post (incorrect for my needs).

I'm not sure how to get the same result as having the "-r 1" be before the input file(s).

coffeemkr0 avatar Aug 09 '23 00:08 coffeemkr0

I managed to get around this using the following code:

FFMpegArguments
            .FromFileInput(Path.Combine(imagesFolderPath, $"%5d{imageExtension}"), false, (Action<FFMpegArgumentOptions>) (options => options.WithFramerate(frameRate)))
            .OutputToFile(outputFileName, addArguments: (Action<FFMpegArgumentOptions>) (options => options.ForcePixelFormat("yuv420p")
            .WithFrameOutputCount(90)))
            .Configure(options => options.WorkingDirectory = imagesFolderPath)
            .Configure(options => options.TemporaryFilesFolder = imagesFolderPath)
            .ProcessSynchronously()

So the part that you would need is adding WithFramerate to your FromFileInput part.

I hope that makes sense.

mdx0111 avatar Jan 15 '24 12:01 mdx0111