feat: corrigido o KeyError 'totalTracks' no cliente MCP: extração
- corrigido o KeyError 'totalTracks' no cliente MCP: extração de structuredContent.data na resposta do servidor (SDK 2.0+) - sincronizado cortes de vídeo e áudio usando razor_all_tracks em vez de split_clip por faixa, eliminando drift entre cortes - atualizado hook para usar razor_all_tracks, isolando vídeo e áudio no mesmo instante - adicionado simulador razor_all_tracks no dublê de teste Resumo: - 5 arquivos alterados - 0 novos - 5 modificados - 0 removidos 5 files changed, 264 insertions(+), 12 deletions(-) Arquivos: - .jhonny/analises.db - code/engine/editor/aplicador_de_plano_de_edicao.py - code/engine/editor/escrita/escrita_no_editor.py - code/engine/integracoes/visual/apple_vision_runner.swift - code/engine/testes/duplos_de_premiere.py
This commit is contained in:
@@ -111,6 +111,7 @@ class ClienteMCPFalso(ClienteMCP):
|
||||
"add_track": self._simular_add_track,
|
||||
"set_playhead_position": self._simular_set_playhead_position,
|
||||
"add_adjustment_layer": self._simular_add_adjustment_layer,
|
||||
"razor_all_tracks": self._simular_razor_all_tracks,
|
||||
"get_clip_at_position": self._simular_get_clip_at_position,
|
||||
"trim_clip": self._simular_trim_clip,
|
||||
"move_clip": self._simular_move_clip,
|
||||
@@ -223,6 +224,46 @@ class ClienteMCPFalso(ClienteMCP):
|
||||
f"No clip strictly spans {instante}s on track {identificador_da_faixa}."
|
||||
)
|
||||
|
||||
def _simular_razor_all_tracks(self, argumentos: dict[str, Any]) -> dict[str, Any]:
|
||||
"""Divide todos os clipes de todas as faixas no instante informado.
|
||||
|
||||
Reproduz o ``razor_all_tracks`` do bridge real: corta todas as faixas
|
||||
de vídeo e/ou áudio no mesmo ponto de tempo, garantindo
|
||||
sincronização entre elas.
|
||||
"""
|
||||
instante_pedido = float(argumentos["time_seconds"])
|
||||
track_type = argumentos.get("track_type", "both")
|
||||
cortados = 0
|
||||
self._salvar_estado()
|
||||
for identificador_da_faixa, faixa in self._faixas.items():
|
||||
if track_type == "video" and not identificador_da_faixa.startswith("video_"):
|
||||
continue
|
||||
if track_type == "audio" and not identificador_da_faixa.startswith("audio_"):
|
||||
continue
|
||||
for posicao, clipe in enumerate(faixa):
|
||||
if clipe.inicio_na_timeline < instante_pedido < clipe.fim_na_timeline:
|
||||
instante = min(
|
||||
max(instante_pedido + self.desvio_do_split, clipe.inicio_na_timeline + 0.001),
|
||||
clipe.fim_na_timeline - 0.001,
|
||||
)
|
||||
deslocamento = instante - clipe.inicio_na_timeline
|
||||
self._proximo_id += 1
|
||||
parte_esquerda = _ClipeFalso(
|
||||
f"{clipe.identificador}_esq{self._proximo_id}", clipe.nome,
|
||||
clipe.inicio_na_timeline, instante,
|
||||
clipe.inicio_na_origem, clipe.inicio_na_origem + deslocamento,
|
||||
)
|
||||
self._proximo_id += 1
|
||||
parte_direita = _ClipeFalso(
|
||||
f"{clipe.identificador}_dir{self._proximo_id}", clipe.nome,
|
||||
instante, clipe.fim_na_timeline,
|
||||
clipe.inicio_na_origem + deslocamento, clipe.fim_na_origem,
|
||||
)
|
||||
faixa[posicao:posicao + 1] = [parte_esquerda, parte_direita]
|
||||
cortados += 1
|
||||
break
|
||||
return {"razored": cortados, "verified": True}
|
||||
|
||||
def _simular_ripple_delete(self, argumentos: dict[str, Any]) -> dict[str, Any]:
|
||||
"""Remove o clipe pedido e fecha o espaço deixado na mesma faixa."""
|
||||
identificador_do_clipe = argumentos["node_id"]
|
||||
|
||||
Reference in New Issue
Block a user