fix(voz): sobra de fatia interior no corte, e legenda comum poluindo com clipe desativado

Dois problemas reais vistos no projeto Mastopexia:

1. cut_clip_ranges só absorvia um keep-segment curto no INÍCIO/FIM do
   clipe (a lógica já existente do #6). Um keep curto no MEIO (entre dois
   cuts, sem nenhum vizinho mantido pra herdar) nunca era absorvido —
   sobrava como clipe de vídeo de 0,07-0,23s na timeline. Generalizado
   pra qualquer posição, com limiar maior (6 frames / 0,3s, medido no
   material real) — no meio, o pedacinho é descartado (vira parte do
   corte ao redor), nas bordas continua sendo herdado pelo vizinho.

2. generate_subtitles_by_emphasis gerava a legenda comum inteira e
   desativava (enabled="0") onde a dinâmica cobre. Título desativado
   continua aparecendo como clipe riscado na timeline do Final Cut mesmo
   sem renderizar — um corte com bastante ênfase virava dezenas de clipes
   mortos poluindo a trilha (visto ao vivo pelo usuário: "ficou uma
   bosta"). Trocado por não gerar o bloco comum ali, em vez de gerar e
   desativar. Custo: reativar ênfase manualmente depois exige regenerar a
   legenda comum daquele trecho, não só reabilitar.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
João Henrique
2026-08-21 18:59:21 -04:00
co-authored by Claude Sonnet 5
parent 8257155fd3
commit 2ad5854570
4 changed files with 97 additions and 45 deletions
+26
View File
@@ -331,6 +331,32 @@ class TestCutClipRanges:
assert mod._parse_time(seg.get("duration")).to_seconds() == pytest.approx(4.0)
assert removed.to_seconds() == pytest.approx(0.0)
def test_interior_sliver_between_two_cuts_is_dropped_not_kept(self, tmp_path):
"""A keep segment under the threshold BETWEEN two cuts (both
neighbors already removed) is the pause between two things that were
cut, not real content — regression for a real voice-edit where
consecutive short cuts left 0.07-0.23s clips surviving between the
real ones. Unlike the edge case, there is no kept neighbor to widen:
the sliver is just dropped, extending the surrounding cut over it."""
from fcpxml.models import TimeValue
mod = self._make_modifier(tmp_path)
clip = self._spine_clips(mod)[0]
# 4s clip; cut 0.5..1.5 and 1.6..3.5 -> would-be keeps: [0..0.5],
# [1.5..1.6] (0.1s interior sliver), [3.5..4].
removed = mod.cut_clip_ranges(clip, [
(TimeValue(1, 2), TimeValue(3, 2)),
(TimeValue(8, 5), TimeValue(7, 2)),
])
clips = self._spine_clips(mod)
assert len(clips) == 3 # interview x2 real segments + broll; no 0.1s sliver
seg1, seg2, broll = clips
assert broll.get("name") == "broll"
assert mod._parse_time(seg1.get("duration")).to_seconds() == pytest.approx(0.5)
assert mod._parse_time(seg2.get("duration")).to_seconds() == pytest.approx(0.5)
assert removed.to_seconds() == pytest.approx(3.0)
def test_markers_follow_their_segment(self, tmp_path):
from fcpxml.models import TimeValue