Skip to content

Commit c458dc6

Browse files
committed
fix: Correct edited video detection heuristic by checking FPS fraction denominator and update uv.lock dependencies.
1 parent 18baae7 commit c458dc6

2 files changed

Lines changed: 28 additions & 7 deletions

File tree

src/Libra/core/video_metadata.py

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,20 @@ def _extract_iphone_model(exif_out: str) -> str | None:
187187

188188
@staticmethod
189189
def _is_edited_fps(file_path: Path) -> bool:
190+
"""Heuristic: re-encoded/edited video tends to have an integer FPS fraction.
191+
192+
Native camera footage uses fractional rates:
193+
- 30000/1001 ≈ 29.97 fps (standard NTSC)
194+
- 60000/1001 ≈ 59.94 fps
195+
Re-encoded/edited footage uses exact integer fractions:
196+
- 30/1 = exactly 30 fps
197+
- 60/1 = exactly 60 fps
198+
199+
Comparing the rounded float (as the original code did) causes false positives
200+
because 30000/1001 rounds to 29.97, not 30.0 — but some recording modes and
201+
screen-recording tools do produce genuine 30/1 or 60/1 streams on unedited
202+
files. Using the denominator is a stronger discriminator.
203+
"""
190204
try:
191205
result = subprocess.run(
192206
[
@@ -207,11 +221,12 @@ def _is_edited_fps(file_path: Path) -> bool:
207221
)
208222
fraction = result.stdout.strip()
209223
if "/" in fraction:
210-
num, den = map(float, fraction.split("/"))
211-
if den > 0:
212-
exact_fps = round(num / den, 6)
213-
if exact_fps in (30.000000, 60.000000):
214-
return True
224+
parts = fraction.split("/", 1)
225+
num, den = float(parts[0]), float(parts[1])
226+
# Native camera: denominator is typically 1001 (e.g. 30000/1001 = 29.97)
227+
# Re-encoded: denominator is 1 (e.g. 30/1, 60/1)
228+
if den > 0 and int(den) == 1 and int(num) in (30, 60):
229+
return True
215230
return False
216231
except (FileNotFoundError, ValueError):
217232
return False

uv.lock

Lines changed: 8 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)