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:
co-authored by
Claude Sonnet 5
parent
8257155fd3
commit
2ad5854570
+33
-16
@@ -195,23 +195,40 @@ class CutMixin:
|
||||
if cursor < clip_duration:
|
||||
keeps.append((cursor, clip_duration))
|
||||
|
||||
# A keep segment shorter than a couple frames at the very start or
|
||||
# end of the clip is just leftover cut padding with no neighboring
|
||||
# kept audio on its outer side (the silence butts against the clip's
|
||||
# own edge) — not a real clip. Rather than emit it as its own
|
||||
# near-invisible micro-clip, fold it into the adjacent real segment,
|
||||
# which simply starts earlier / ends later to absorb it.
|
||||
min_keep_seconds = 2 * float(self.frame_duration_fraction())
|
||||
if len(keeps) > 1:
|
||||
first_start, first_end = keeps[0]
|
||||
if (first_end - first_start).to_seconds() < min_keep_seconds:
|
||||
keeps[1] = (first_start, keeps[1][1])
|
||||
# A keep segment shorter than MIN_KEEP_SECONDS is leftover between
|
||||
# two cuts, not a real clip — at the very start/end of the clip it's
|
||||
# cut padding with no kept audio on the outer side; in the interior
|
||||
# it's the pause BETWEEN two things that were both cut (e.g. two
|
||||
# consecutive deactivated phrases in the voice-editing flow), which
|
||||
# belongs to neither side by construction. At the edges we fold it
|
||||
# into the one neighboring KEEP segment there is, which simply starts
|
||||
# earlier / ends later to absorb it. In the interior both neighbors
|
||||
# are CUT, not keep, so there is nothing to fold into — it is just
|
||||
# dropped, extending the surrounding cut across it instead of
|
||||
# surviving as a third near-invisible micro-clip.
|
||||
#
|
||||
# The threshold is bigger than one frame on purpose: measured on a
|
||||
# real voice-edit (0.07-0.23s residues), a single frame did not catch
|
||||
# them — this is pause/padding leftover, not intentional short
|
||||
# content, so treating anything under a third of a second this way
|
||||
# is safe for this cut path.
|
||||
min_keep_seconds = max(6 * float(self.frame_duration_fraction()), 0.3)
|
||||
i = 0
|
||||
while len(keeps) > 1 and i < len(keeps):
|
||||
start, end = keeps[i]
|
||||
if (end - start).to_seconds() >= min_keep_seconds:
|
||||
i += 1
|
||||
continue
|
||||
if i == 0:
|
||||
keeps[1] = (start, keeps[1][1])
|
||||
keeps.pop(0)
|
||||
if len(keeps) > 1:
|
||||
last_start, last_end = keeps[-1]
|
||||
if (last_end - last_start).to_seconds() < min_keep_seconds:
|
||||
keeps[-2] = (keeps[-2][0], last_end)
|
||||
keeps.pop()
|
||||
elif i == len(keeps) - 1:
|
||||
keeps[i - 1] = (keeps[i - 1][0], end)
|
||||
keeps.pop(i)
|
||||
else:
|
||||
keeps.pop(i)
|
||||
# Re-check the same index: the segment now there might itself be
|
||||
# short enough to absorb again (two short keeps in a row).
|
||||
|
||||
spine.remove(clip)
|
||||
new_clips: List[ET.Element] = []
|
||||
|
||||
Reference in New Issue
Block a user