fix(mux): pass the exact frame rate to mkvmerge default duration

FPS.exact keeps 24000/1001 instead of rounding to 23.976, and the hybrid source copies no longer set needs_duration_fix, which nothing read.
This commit is contained in:
imSp4rky
2026-11-14 11:17:07 -07:00
parent 6964f58271
commit dfda630b78
6 changed files with 40 additions and 5 deletions
+29
View File
@@ -1,7 +1,10 @@
import warnings
from pathlib import Path
from typing import Callable
import pytest
from unshackle.core.tracks import Tracks, Video
from unshackle.core.utilities import FPS
@@ -27,3 +30,29 @@ def test_parse_rejects_non_numeric_constant() -> None:
def test_parse_rejects_non_division_operation() -> None:
with pytest.raises(ValueError, match="Invalid operation"):
FPS.parse("24+1")
@pytest.mark.parametrize(
("fps", "expected"),
[
(24000 / 1001, "24000/1001"),
(23.976, "24000/1001"),
(23.97, "24000/1001"),
(59.94, "60000/1001"),
(24.0, "24"),
(25, "25"),
(5, "5"),
(12.5, "25/2"),
],
)
def test_exact_keeps_ntsc_rates(fps: float, expected: str) -> None:
assert str(FPS.exact(fps)) == expected
def test_mux_passes_the_exact_rate_as_default_duration(tmp_path: Path, mux_args: Callable[..., list[str]]) -> None:
video = Video(id_="v1", url="https://example.test/v", codec=Video.Codec.HEVC, language="en", fps="24000/1001")
video.needs_duration_fix = True
video.path = tmp_path / "v.hevc"
video.path.write_bytes(b"\x00" * 16)
args = mux_args(Tracks(video))
assert args[args.index("--default-duration") + 1] == "0:24000/1001p"