# 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](https://www.rust-lang.org/tools/install) (edição 2024) - [`ffmpeg`](https://ffmpeg.org/download.html) disponível no `PATH` - [`ffprobe`](https://ffmpeg.org/download.html) disponível no `PATH` (incluso na maioria das instalações do FFmpeg) Verificar disponibilidade: ```bash ffmpeg -version ffprobe -version ``` --- ## Instalação e Execução ```bash # Clonar o repositório git clone 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 ```bash 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.