manim icon indicating copy to clipboard operation
manim copied to clipboard

Variable framerate fix for all branches

Open qo4on opened this issue 5 years ago • 4 comments

  1. Manim generates variable framerate video instead of the constant value in the CONFIG

  2. mp4fpsmod tool can fix this. Unzip the attachment to manim folder and place this code to line 500 of scene_file_writer.py right after combine_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'
)

mp4fpsmod.zip

qo4on avatar Jul 31 '20 15:07 qo4on

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?

3b1b avatar Feb 06 '21 18:02 3b1b

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.

qo4on avatar Feb 06 '21 22:02 qo4on

But without -vf scale=out_color_matrix=bt709 the error is around -10...+10.

There is no error there. It just defaults to bt601 matrix. Which is different. Oogh.

ValZapod avatar Aug 28 '21 13:08 ValZapod

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

RadicalGDPRist avatar Jun 24 '22 16:06 RadicalGDPRist