4

Pitch: Vayou — Player de Vídeo Nativo que Traduz a Legenda Sozinho (Rust + Slint)

Fiz um player de vídeo para Windows e Linux em Rust + Slint. Ele existe por dois motivos: traduzir legenda sem eu sair do player e não pesar.

Vayou tocando um vídeo — janela sem borda, barra de título própria, controles sobre a imagem

Legenda

Você abre um filme que só tem legenda em inglês e escolhe o idioma. O app extrai a faixa embutida com ffmpeg, traduz em blocos e devolve como faixa externa, preservando a formatação ASS — posição, cor, itálico. São 12 idiomas, e dá para fixar um: aí ele faz isso sozinho a cada arquivo que você abre.

Arquivo sem legenda nenhuma? Busca e baixa do OpenSubtitles de dentro do player. E ele lembra qual faixa de áudio e de legenda você escolheu por arquivo — não um ajuste global que você refaz a cada episódio.

Performance

O Vayou nasceu em Tauri + Svelte: um WebView desenhando controles por cima de um vídeo, com RAM de navegador. Reescrevi do zero em Rust nativo — um processo só, sem WebView. Escolhi o Slint justamente para ter versão Linux: o mesmo código roda nos dois sistemas, e só a moldura da janela tem implementação separada.

Não existe janela de vídeo separada. O mpv roda com vo=libmpv e desenha dentro do mesmo framebuffer OpenGL que o Slint usa: o femtovg limpa o back buffer, o mpv desenha o frame com as legendas, e o Slint pinta a UI por cima com fundo transparente onde tem vídeo. Uma janela, um swapchain, nenhum frame passeando pela CPU só para chegar na tela.

A armadilha que me custou mais tempo: no Linux, o contexto de render precisa receber o display X11/Wayland. Sem isso o libmpv não abre um VA display e cai para decodificação por software em silêncio — sem erro, sem aviso, o único sintoma é a CPU no talo.

O resto

Reproduçãovelocidade 0.25–4×, frame a frame, loop A–B, capítulos, abrir por URL, retomar de onde parou, sleep timer
Áudiomúltiplas faixas, equalizador com presets, normalização, boost até 200%, delay
Vídeobrilho/contraste/saturação, aspect ratio, desentrelaçamento, zoom e pan
Janelasem borda, sempre no topo, drag & drop, atalhos remapeáveis, 12 idiomas de interface

Sendo honesto

  • MIT, código aberto. Instalador por usuário, sem admin — mas sem assinatura, então o SmartScreen avisa na primeira execução.
  • O instalador do Windows não é leve: o binário tem 8,8 MB, mas carrega libmpv e ffmpeg junto porque o Windows não tem nenhum dos dois. No Linux os dois vêm da distro.
  • A tradução usa um endpoint não oficial do Google Translate. Pode limitar sem aviso — o app diz quando um trecho não foi traduzido em vez de fingir que foi.
  • Sempre no topo é só X11. No Wayland quem empilha janela é o compositor, e o app fala isso em vez de deixar o botão aceso sobre uma janela que não subiu.

No Arch, onde o pacote consegue declarar que precisa de libmpv e ffmpeg:

curl -O https://raw.githubusercontent.com/0hgawa/vayou-slint/master/installer/PKGBUILD
makepkg -si

Feedback é bem-vindo, principalmente de quem rodar GPU AMD no Linux — é a combinação que eu menos consigo testar aqui.

Carregando publicação patrocinada...
1

+3

Sensacional o projeto!

Teria como criar um CLI/Binário para conseguir só enviar o video e exportar as legendas?

Acredito que fazendo isso daria para acoplar facilmente em outros projetos.

Algo como:

vayou-cli extract --input "video.mkv" --target-lang "pt-BR" --output "legenda.ass"

Como venho construindo o CroMedia e lidando com pipelines de processamento e engenharia de mídia, ter uma ferramenta de linha de comando focada apenas nessa extração e tradução automatizada seria absurdamente útil para integrar em rotinas de backend. A lógica de tradução e chunking no Rust está isolada o suficiente no repositório para gerar um binário CLI separado?

Sobre o seu pedido de feedback em AMD no Linux: meu ambiente principal roda Linux Mint com um Ryzen 5. Para te dar um dado mais preciso sobre a renderização e o uso do VA display, cria um template ou script de benchmark padronizado que seja simples de executar. Assim que você disponibilizar, eu rodo o teste por aqui e te mando os logs limpos para você ter uma base de análise melhor sobre como o hardware AMD está se comportando.

Parabéns pelo lançamento!

4

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!

0

Vayou para Android — Vídeo, Música e IPTV num app só (Kotlin + Compose)

Fiz a versão Android do Vayou, meu player de vídeo. Só que no celular ele cresceu: virou também player de música e cliente de IPTV, e toca arquivo de compartilhamento de rede sem baixar.

Kotlin + Jetpack Compose + Media3/ExoPlayer, com um decodificador FFmpeg embutido para os formatos que o hardware do aparelho recusa — e dá para forçar um ou outro, quando você quer descobrir qual dos dois é o culpado.

Vayou tocando um vídeo no celular

Dois apps, um código

Celular e tabletAndroid TV
Iddev.vayoudev.vayoutv
InterfaceMaterial 3, para o dedoandroidx.tv.material3, para o controle a 3 metros
Compartilhadoo player, a biblioteca, o banco, a rede, os tokens de design

São listagens e instalações separadas — um celular não é uma televisão, e as duas não dividem tela nenhuma. Mas tudo abaixo da interface é o mesmo código.

Música

Biblioteca própria: músicas, playlists, pastas, álbuns, artistas. Fila que você reordena segurando a linha. Edição de tag e troca de capa dentro do app.

O equalizador é de 5 bandas — 60, 230, 910, 3600 e 14000 Hz — usando o efeito do próprio Android, então vale para o que estiver tocando. Tem preset para flat, voz, clássica, dance, folk, heavy metal, hip hop, jazz, pop e rock, além da sua curva.

O preset de voz existe porque nenhuma curva de gênero serve para fala: ele corta o ronco abaixo de 300 Hz e levanta as consoantes na região de 3,6 kHz. É isso que "não dá para entender o que estão falando" quer dizer, na prática.

Rede — SMB e IPTV

  • SMB: compartilhamentos descobertos na rede ou adicionados por endereço, navegados e tocados sem baixar. Dá para fixar as pastas que você abre sempre.
  • IPTV: listas M3U adicionadas por endereço, navegáveis por país ou grupo, com favoritos.
  • Google Cast: aqui tem um detalhe que eu gosto — o celular serve o arquivo ao receptor pela rede local. O Chromecast busca, em vez de receber uma cópia empurrada. A legenda vai junto.
BibliotecaMúsicaRede
BibliotecaMúsicaRede

Legenda

O mesmo motivo pelo qual escrevi a versão de desktop:

  • Faixas embutidas e externas, do arquivo ou escolhidas do armazenamento
  • Busca no OpenSubtitles, por arquivo ou por nome
  • Tradução ao vivo da legenda em execução
  • Ajuste de atraso, para frente e para trás
  • Estilo completo: fonte, tamanho, posição, cor, contorno, sombra, plaquinha de fundo, negrito — ou respeitar o estilo com que a legenda foi escrita, ou entregar a questão inteira para as legendas do próprio Android

O resto que vale citar

  • Picture in picture — o filme encolhe num canto quando você sai
  • Sleep timer, inclusive na opção quando este acabar
  • Pular silêncio, brilho lembrado entre filmes, trava de controles para a palma da mão não fazer nada
  • Brilho ambiente: as barras laterais do filme assumem a cor dele
  • Miniaturas geradas de um quadro que você escolhe — o primeiro, um mais adiante depois dos créditos de abertura, ou mais adiante com plano B quando aquele quadro é uma cor chapada
  • Acervo Privado, para o que não deve aparecer na biblioteca
  • Onze idiomas, com RTL diagramado de verdade, não espelhado por acidente

Sendo honesto

  • GPL-3, código aberto. (O desktop é MIT — projetos diferentes, licenças diferentes.)
  • O app de Android TV ainda não está publicado na loja. Sai do mesmo repositório, mas por enquanto só compilando você mesmo.
  • A tradução de legenda usa um endpoint não oficial do Google Translate. Pode limitar por volume ou parar de responder sem aviso.
  • minSdk 23, ou seja, Android 6 para cima.

Feedback é bem-vindo — principalmente sobre formatos que não abrirem, que é onde o decodificador embutido deveria salvar e às vezes não salva.