Simple Multimedia Track Audio Editor

Editor simples de faixas multimídia para combinar vídeo, áudio e legendas em um único arquivo MKV — sem reencoding, apenas mux e ajuste de timestamps.


Sobre o Projeto

Este software é um tradutor entre a complexidade do FFmpeg e a simplicidade que o usuário precisa. Em vez de lidar com índices de stream, flags e argumentos técnicos, o usuário trabalha com uma interface direta:

  • "Áudio em português está 1.2 segundos atrasado"
  • "Quero adicionar a legenda em inglês"
  • "Gerar o arquivo final"

O MKV é tratado como um banco de dados multimídia: as operações são INSERT de faixas, UPDATE de timestamps e SELECT de informações via ffprobe. Nenhum byte de mídia é reprocessado.


Funcionalidades

  • Selecionar arquivo de vídeo base
  • Listar automaticamente as faixas existentes (áudio, legenda, vídeo) via ffprobe
  • Adicionar uma ou mais faixas de áudio externas
  • Adicionar uma ou mais faixas de legenda
  • Definir offset de sincronização por faixa (ex: +1.2s, -0.5s)
  • Editar o offset de faixas já presentes no arquivo original
  • Atribuir código de idioma ISO 639-2 a cada faixa (ex: por, eng)
  • Exportar faixas individuais para arquivo separado
  • Remover faixas externas adicionadas antes de gerar o arquivo
  • Gerar arquivo MKV com todas as faixas configuradas
  • Progresso em tempo real durante a geração
  • Cancelar a geração em andamento
  • Exibição legível de erros do FFmpeg

Pré-requisitos

  • Rust (edição 2024)
  • ffmpeg disponível no PATH
  • ffprobe disponível no PATH (incluso na maioria das instalações do FFmpeg)

Verificar disponibilidade:

ffmpeg -version
ffprobe -version

Instalação e Execução

# Clonar o repositório
git clone <url-do-repositorio>
cd simple-multimidia-track-audio-editor

# Verificar compilação
cargo check

# Rodar os testes
cargo test

# Executar a aplicação
cargo run

Como Usar

  1. Selecionar vídeo — clique em "Selecionar vídeo" e escolha o arquivo base. As faixas existentes serão detectadas automaticamente.
  2. Adicionar faixas — use os formulários para adicionar áudio externo ou legendas. Configure idioma e offset de sincronização.
  3. Editar faixas existentes — ajuste o offset de faixas já presentes no arquivo original diretamente na lista.
  4. Definir saída — escolha o caminho do arquivo MKV de saída.
  5. Gerar — clique em "Gerar MKV". O progresso é exibido em tempo real. É possível cancelar a qualquer momento.

Garantias do Domínio

Invariante Descrição
Sem reencoding -c copy está sempre presente no comando gerado — nunca opcional, nunca configurável
SyncOffset sem ponto flutuante Armazenado como i64 em milissegundos; a conversão para o formato do FFmpeg ocorre exclusivamente no adapter
TrackId opaco Não expõe índices internos do FFmpeg; o mapeamento para -map N:tipo é feito apenas no adapter
Output ≠ Source O projeto rejeita em construção se o caminho de saída for igual ao de entrada

Arquitetura

O projeto segue Clean Architecture com dependências sempre apontando de fora para dentro:

UI (egui/eframe)
    └── Adapters (FfmpegGateway, FfprobeGateway, FilePickerAdapter)
            └── Application (Use Cases + Ports)
                    └── Domain (Entities + Value Objects)

Estrutura de pastas

src/
├── domain/
│   ├── entities/        # Project, VideoFile, AudioTrack, SubtitleTrack, MkvOutput, MediaTrackInfo
│   └── value_objects/   # TrackId, SyncOffset (ms/i64), TrackLanguage, FilePath
├── application/
│   ├── use_cases/       # LoadMediaInfo, AddAudioTrack, AddSubtitle, AdjustSync, GenerateOutput, ...
│   └── ports/           # Traits: MediaProcessorPort, MediaInfoPort, FileSystemPort
├── adapters/
│   ├── ffmpeg/          # FfmpegCommandBuilder, FfmpegGateway, FfprobeGateway
│   └── filesystem/      # FilePickerAdapter
├── infrastructure/
│   └── process/         # Execução assíncrona do FFmpeg (tokio), cancelamento via oneshot
├── ui/
│   ├── app.rs           # eframe::App — Project como única fonte de verdade
│   └── components/      # Componentes egui reutilizáveis
└── main.rs

Stack tecnológica

Camada Tecnologia
Interface egui / eframe 0.27
Backend Rust (std::process::Command)
Async tokio 1.x
Erros anyhow
Serialização serde + serde_json
Diálogos nativos rfd 0.14
Container de saída MKV (Matroska)

Testes

33 testes unitários cobrindo:

  • Value objects: SyncOffset, TrackLanguage, FilePath, TrackId
  • Entidades: Project (validações de invariantes)
  • Use cases: todos com mocks (sem I/O real)
  • FfmpegCommandBuilder: presença de -c copy, formato de -itsoffset, mapeamento de -map
  • ExportTrack: comportamento por tipo de faixa
  • RemoveTrack: remoção e erro para ID inexistente
cargo test

Escopo da v1.0

Incluso:

  • Mux de múltiplas faixas de áudio e legenda
  • Ajuste de timestamps por faixa
  • Leitura de faixas existentes via ffprobe
  • Interface gráfica nativa multiplataforma

Fora do escopo:

  • Reencoding / transcodificação
  • Preview de vídeo embutido
  • Detecção automática de sincronização
  • Remoção de faixas existentes do arquivo original
  • Processamento em lote (batch)
  • Persistência do estado do projeto em disco

Licença

A definir.

S
Description
No description provided
Readme
469 KiB
Languages
Rust 100%