Obrigado, colega!!
Fui conferir no código antes de responder, porque a resposta honesta é sim, mas o acoplamento não está onde parece.
A lógica não está presa à UI. services/translate.rs e services/subtitle_extract.rs não importam Slint em lugar nenhum — o segundo é ffmpeg como sidecar mais parsing/escrita de SRT/ASS, puro. O chunking (~4500 chars por request, respeitando os \n\n que juntam as entries), o fan-out limitado por Semaphore em 8 requests simultâneas e o passe de retry serial estão todos em translate_job.rs, também sem UI.
O acoplamento que existe é com o mpv, e ele é raso: dentro do run() o player é usado pra ler qual arquivo está tocando, listar as tracks (pra escolher a fonte e detectar legenda em imagem), e no fim carregar o resultado. Num CLI o primeiro vira --input, o segundo vira ffprobe, e o terceiro desaparece — o arquivo já é escrito em disco antes disso. É refatorar o topo do run() pra receber parâmetros em vez de perguntar ao player, não reescrever.
A forma certa seria um workspace: um crate vayou-subs com extract + chunk + translate, e player e CLI consumindo os dois. Se eu só adicionasse um [[bin]] no crate atual, o binário linkaria Slint e femtovg junto, o que derrota o propósito de acoplar em backend.
Duas coisas que já funcionam e que provavelmente te interessam mais do que a CLI em si:
O header ASS é preservado. Extração de header e diálogo saem de uma única passada do ffmpeg, e a reescrita mantém o estilo — não é SRT achatado.
Já tem cache e marcador de parcial. O resultado é determinístico pra um dado (vídeo, track, idioma), então uma segunda chamada devolve o arquivo em vez de redemuxar — o que num remux de 22 GB é a diferença entre 134s e instantâneo. E se algum chunk cair mesmo depois do retry, o arquivo sai marcado como parcial em vez de passar por completo. Isso é comportamento de pipeline, não de player.
O ponto que eu levantaria antes de você planejar em cima disso: o backend de tradução é o endpoint não-documentado do Google. Pra uso interativo num player é ótimo; pra rotina de backend em volume, é exatamente onde vai doer — rate limit, bloqueio, zero garantia, e nada disso avisa antes. Então se eu fizer a CLI, o backend nasce plugável, e não com o Google chumbado dentro. É a única parte do desenho que eu não quero errar de primeira. Se você já tem preferência de provedor pelo CroMedia, me fala — isso ajuda a definir a interface.
Sobre o benchmark: ótimo, aceito, só fiz no Arch. Vou montar um script que roda o teste e já sai com a saída limpa — hoje dá pra ter uma prévia rodando com VAYOU_LOG=debug e procurando a linha decoder in use: qualquer coisa diferente de no significa que a GPU está decodificando (vaapi no seu caso). Se ela vier no, é sinal de que o VA display não abriu, que é exatamente a falha silenciosa que eu quero pegar. Te aviso quando o script estiver no repo.
Obrigado pelo interesse!