Skip to content

Handle FFmpeg builds without drawtext - #112

Merged
kstonekuan merged 1 commit into
Hebbian-Robotics:mainfrom
promiseeuler:codex/contact-sheet-drawtext-fallback
Aug 23, 2026
Merged

Handle FFmpeg builds without drawtext#112
kstonekuan merged 1 commit into
Hebbian-Robotics:mainfrom
promiseeuler:codex/contact-sheet-drawtext-fallback

Conversation

@promiseeuler

@promiseeuler promiseeuler commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

Summary

While testing HFlow's contact-sheet helper on macOS, I found that a usable system font could make it attempt timestamp burn-in even when the selected FFmpeg binary does not provide the drawtext filter. This change detects that capability and gracefully produces an untimestamped sheet when it is unavailable.

Fixes #111.

Why

The documented fallback covered a missing font but not a missing FFmpeg filter. Standard Homebrew FFmpeg builds can expose scale and tile without drawtext, causing the whole contact-sheet operation to fail instead of returning timestamps_burned=False.

The capability result is cached per resolved FFmpeg path, and the existing binary is reused for the actual render.

Validation

uv sync --locked --all-extras

uv run pytest -q tests/test_ffmpeg.py::test_contact_sheet_grid_geometry tests/test_ffmpeg.py::test_contact_sheet_without_drawtext_still_produces_sheet tests/test_ffmpeg.py::test_contact_sheet_max_tiles_sampling — 3 passed

uv run ruff check src/hflow/ffmpeg/_contact_sheet.py tests/test_ffmpeg.py — passed

uv run ruff format --check src/hflow/ffmpeg/_contact_sheet.py tests/test_ffmpeg.py — passed

uv run ty check — passed

Checklist

Outcome-focused tests added for the changed business logic.

Documentation updated for the changed fallback behavior.

Ruff lint, Ruff formatting check, and ty check passed.

Relevant pytest cases passed.

No recordings, generated media, credentials, private URLs, or runtime artifacts were added.

Stored-data compatibility is unchanged.

@kstonekuan kstonekuan left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Merging.

Computing timestamps_burned once instead of re-deriving it at the bottom is the part that fixes the shape and not just the bug, and @cache keyed on the binary path rather than a module flag is the right call. assert font_file is not None matches the existing narrowing convention (batching.py:80, episode.py:128), so no change wanted.

Validated against main (9d59310): gates clean, 406 passed, 3 skipped. Also confirmed the new predicate returns True on a build that does have drawtext, since silently disabling burn-in for everyone was the failure mode worth ruling out.

Three things you should know:

#108 was fixed by @WilliamK112 in #110. You filed it and specified the fix that landed. It was unassigned and only an assignee reserves an issue, so they were entitled to it, but you found it. Comment on anything you intend to take and I will assign it.

#107 can be reopened, it was closed by the one-open-PR cap, not on merit.

#96 and #97 are both unclaimed and your analysis on each is useful. You answered the ordering question on #96 from the source, and you found an error in my #97 spec, which I have corrected there. Say the word on either.

@kstonekuan
kstonekuan merged commit dee641b into Hebbian-Robotics:main Aug 23, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ffmpeg: contact_sheet fails when a font exists but drawtext is unavailable

2 participants