Skip to content

Feature request: record should support strict constant-frame-rate (CFR) output for low-FPS animations #5593

@ryofurue

Description

@ryofurue

[I generated this report with ChatGPT and edited it.]

Summary
When using record to generate low-frame-rate videos (e.g., 1–5 fps), the resulting MP4 files may exhibit frame skipping or merging in some players (notably VLC), even when framerate is explicitly specified. This suggests that the current encoding does not enforce strict constant-frame-rate timing and/or uses inter-frame compression that interferes with discrete frame sequences.

Environment

  • Julia + Makie (via record)
  • Output format: MP4
  • Example: 2 fps, ~80 frames, ~600×450 resolution

Observed behavior
Animations constructed as discrete frames (e.g., one frame per “day”) do not reliably display every frame in some players. Frames may be skipped, merged, or briefly “paused over” before jumping ahead.

Expected behavior
Each frame passed to record should be displayed exactly once for the intended duration across standard players, independent of player-specific frame-dropping heuristics.

Likely cause
The encoded video appears to have one or more of:

  • Variable frame rate (VFR) or non-uniform presentation timestamps
  • GOP size > 1 (inter-frame compression with P/B frames)
  • Missing/loose CFR signaling in the container

These can cause players to drop or reschedule frames, especially at very low FPS.

Proposed enhancement
Provide an option in record to enforce strict CFR output with intra-only frames. Conceptually, this corresponds to:

  • Uniform, monotonic timestamps (true CFR)
  • GOP size = 1 (all frames are keyframes)
  • Avoidance of B/P frames for deterministic presentation

Notes

I tried to fix this with ffmeg and was successful with

ffmpeg -i input.mp4 -vf fps=2 -vsync cfr -r 2 -g 1 -pix_fmt yuv420p output.mp4

where

  • -vsync cfr → enforce constant frame rate
  • -r 2 → 2 fps
  • -g 1 → every frame is a keyframe

Rationale
For scientific or data-driven animations, each frame usually encodes a discrete state (e.g., time steps, simulation outputs). For such use cases, exact frame fidelity is more important than compression efficiency or playback smoothing. Providing a built-in, documented way to guarantee this would prevent subtle cross-player inconsistencies.

Workaround (current)
Post-process the generated file with:

ffmpeg -i input.mp4 -vf fps=2 -vsync cfr -r 2 -g 1 output.mp4

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementFeature requests and enhancements

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions