FFMpegCore
FFMpegCore copied to clipboard
Issue with frame rate argument (r) when joining images
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.
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).
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.