manim
manim copied to clipboard
Variable framerate fix for all branches
-
Manim generates variable framerate video instead of the constant value in the CONFIG
-
mp4fpsmodtool can fix this. Unzip the attachment to manim folder and place this code to line500ofscene_file_writer.pyright aftercombine_process.wait().
Note: this tool does not work if you have opened the video file in another program.
mp4fpsmod_file_path = os.path.join(
os.getcwd(),
'mp4fpsmod.exe' if os.name == 'nt' else 'mp4fpsmod'
)
fix_timestamps_process = subprocess.Popen([
mp4fpsmod_file_path,
'--fps', '0:' + str(self.scene.camera.frame_rate),
'--timescale', '15360',
movie_file_path, '--inplace'
])
fix_timestamps_process.wait()
Or
mp4fpsmod_file_path = os.path.join(
os.path.dirname(
os.path.dirname(
os.path.dirname(__file__))),
'mp4fpsmod.exe' if os.name == 'nt' else 'mp4fpsmod'
)
See this comment.
Still, even if this usage of concat is no longer the default, this might be worth fixing for the concat case in case anyone wants all the animations written to separate files. Is there a way to specify this using ffmpeg, rather than calling mp4fpsmod?
You are right, the separate files have constant frame rate. If they are the goal, you don't need to change anything. For example, if a user concatenates them in Premiere Pro he will get CFR output without any problem.
Is there a way to specify this using ffmpeg, rather than calling mp4fpsmod?
I did not find a way to do this. mp4fpsmod does it in fast lossless mode without any reencoding. ffmpeg can't rearrange frames timestamps losslessly.
ffmpeg is a very buggy thing, it should be used cautiously. Manim also had a problem with wrong colors during png to mp4 conversion. ffmpeg incorrectly defines the output color space. You must add -vf scale=out_color_matrix=bt709 to any rgb to yuv conversion. rgb to yuv always have an error in 8-bit video. But this error should be small: the colors are not exactly the same, they are in a range -2...+2 rgb values. But without -vf scale=out_color_matrix=bt709 the error is around -10...+10.
Also ffmpeg is almost useless when it comes to audio. It changes the waveform and duration of mp3 file when you do mp3 to wav. Many audio filters like alimiter add artifacts...
Another Manim issue I fixed with this wrapper:
def time_cor(run_time, time_shift=0, frame_time=1 / 60):
whole, rem = divmod(run_time, frame_time)
if rem + time_shift > frame_time / 2:
run_time = (whole + 1) * frame_time
time_shift += rem - frame_time
else:
run_time = whole * frame_time
time_shift += rem
return run_time, time_shift
I wrapped every run_time with this function to fix "rounding to frame" time error. Imagine you have 1000 small partial video clips and run_time of each of them cannot be divided by fps without a reminder. This means you will get a final video a few seconds longer than expected.
But without
-vf scale=out_color_matrix=bt709the error is around -10...+10.
There is no error there. It just defaults to bt601 matrix. Which is different. Oogh.
Doesn't this tool only change the PTS and DTS? There's -bsf:v 'setts=dts... in ffmpeg as argued based on and over here