feat: atualiza versão do projeto para 1.3 e revisa o plano de desenvolvimento e PRD com novas funcionalidades e requisitos
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
# PRD — Simple Multimedia Track Audio Editor
|
||||
|
||||
**Versão:** 1.1
|
||||
**Versão:** 1.2
|
||||
**Data:** 28/02/2026
|
||||
**Status:** Em desenvolvimento
|
||||
**Revisão:** Incorporados feedbacks de arquitetura — modelo de sessão, ffprobe, tipos fortes e regra de no-reencode
|
||||
**Revisão:** v1.2 — Adicionado RF-09 (Modo Lote); batch promovido de backlog para requisito planejado
|
||||
|
||||
---
|
||||
|
||||
@@ -105,6 +105,17 @@ As ferramentas existentes são complexas (ex: interface direta do FFmpeg via CLI
|
||||
- A faixa original é remapeada com o novo timestamp via `ffmpeg -itsoffset` combinado com `-map`
|
||||
- Útil para corrigir atrasos em faixas de dublagem ou legenda já incorporadas ao arquivo
|
||||
|
||||
### RF-09 — Processamento em lote
|
||||
|
||||
- A interface oferece duas abas: **Projeto Único** (fluxo atual) e **Lote**
|
||||
- A aba Lote funciona como um **carrinho**: o usuário adiciona, revisa e remove itens livremente antes de processar
|
||||
- Cada item é um projeto completo e independente (vídeo, faixas e saída próprios), configurado via **formulário inline** na própria aba Lote — sem navegação para outra tela
|
||||
- A seleção de arquivos usa **diálogos nativos** (igual ao modo Projeto Único) — nenhum path é digitado manualmente
|
||||
- O processamento é **sequencial** — um projeto por vez, sem paralelismo, para evitar sobrecarga de I/O
|
||||
- Durante o processamento, o carrinho é bloqueado: não é possível adicionar nem remover itens
|
||||
- Cada item exibe seu estado individual: `Aguardando | Processando | Concluído | Erro`
|
||||
- É possível cancelar o item em execução; os demais permanecem no carrinho com estado `Aguardando`
|
||||
|
||||
---
|
||||
|
||||
## 7. Requisitos Não Funcionais
|
||||
@@ -158,15 +169,15 @@ Arquivo de saída (.mkv)
|
||||
|
||||
### Stack
|
||||
|
||||
| Camada | Tecnologia | Motivo |
|
||||
|--------------|-------------------------------|---------------------------------------------|
|
||||
| Interface | `egui` / `eframe` | Nativo, simples, multiplataforma |
|
||||
| Backend | Rust (`std::process::Command`)| Estável, sem dependências externas |
|
||||
| Erros | `anyhow` | Propagação de erros simplificada |
|
||||
| Configuração | `serde` | Serialização de perfis e histórico |
|
||||
| Async | `tokio` (opcional) | Execução não bloqueante da interface |
|
||||
| Mídia | FFmpeg (externo) | Maduro, estável, amplamente testado |
|
||||
| Container | MKV | Melhor suporte a múltiplas faixas |
|
||||
| Camada | Tecnologia | Motivo |
|
||||
| ------------ | ------------------------------ | ------------------------------------ |
|
||||
| Interface | `egui` / `eframe` | Nativo, simples, multiplataforma |
|
||||
| Backend | Rust (`std::process::Command`) | Estável, sem dependências externas |
|
||||
| Erros | `anyhow` | Propagação de erros simplificada |
|
||||
| Configuração | `serde` | Serialização de perfis e histórico |
|
||||
| Async | `tokio` (opcional) | Execução não bloqueante da interface |
|
||||
| Mídia | FFmpeg (externo) | Maduro, estável, amplamente testado |
|
||||
| Container | MKV | Melhor suporte a múltiplas faixas |
|
||||
|
||||
### Dependências Cargo
|
||||
|
||||
@@ -208,10 +219,10 @@ As dependências sempre apontam de fora para dentro. Camadas internas não conhe
|
||||
|
||||
Contém as entidades e objetos de valor do negócio. Não depende de nada externo.
|
||||
|
||||
| Tipo | Exemplos |
|
||||
|----------------|-----------------------------------------------------------------------------------|
|
||||
| Entities | `Project`, `VideoFile`, `AudioTrack`, `SubtitleTrack`, `MkvOutput`, `MediaTrackInfo` |
|
||||
| Value Objects | `TrackId`, `SyncOffset`, `TrackLanguage`, `FilePath` |
|
||||
| Tipo | Exemplos |
|
||||
| ------------- | ------------------------------------------------------------------------------------ |
|
||||
| Entities | `Project`, `VideoFile`, `AudioTrack`, `SubtitleTrack`, `MkvOutput`, `MediaTrackInfo` |
|
||||
| Value Objects | `TrackId`, `SyncOffset`, `TrackLanguage`, `FilePath` |
|
||||
|
||||
> **`Project`** é a entidade central do domínio. Representa a sessão de edição completa do usuário e deve ser a única fonte de verdade do estado em memória.
|
||||
>
|
||||
@@ -232,10 +243,10 @@ Contém as entidades e objetos de valor do negócio. Não depende de nada extern
|
||||
Contém as regras de negócio da aplicação. Orquestra as entidades do domínio.
|
||||
Define traits (ports) que as camadas externas devem implementar.
|
||||
|
||||
| Tipo | Exemplos |
|
||||
|------------|-------------------------------------------------------------------------------------------------------------------|
|
||||
| Use Cases | `LoadMediaInfo`, `AddAudioTrack`, `AddSubtitle`, `AdjustSync`, `EditExistingTrackSync`, `SetTrackLanguage`, `GenerateOutput` |
|
||||
| Ports | `MediaProcessorPort`, `MediaInfoPort`, `FileSystemPort` |
|
||||
| Tipo | Exemplos |
|
||||
| --------- | ---------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Use Cases | `LoadMediaInfo`, `AddAudioTrack`, `AddSubtitle`, `AdjustSync`, `EditExistingTrackSync`, `SetTrackLanguage`, `GenerateOutput` |
|
||||
| Ports | `MediaProcessorPort`, `MediaInfoPort`, `FileSystemPort` |
|
||||
|
||||
> **`MediaInfoPort`** é o port responsável por inspecionar arquivos de mídia existentes. Deve ser definido na camada Application e implementado na camada Adapters via `FfprobeGateway`.
|
||||
>
|
||||
@@ -253,11 +264,11 @@ Define traits (ports) que as camadas externas devem implementar.
|
||||
|
||||
Implementam os ports definidos na camada de Application. Traduzem dados entre o domínio e o mundo externo.
|
||||
|
||||
| Tipo | Exemplos |
|
||||
|--------------------|---------------------------------------------------------------------------|
|
||||
| Gateway | `FfmpegCommandBuilder`, `FfmpegGateway`, `FfprobeGateway` |
|
||||
| Presenter | `ErrorPresenter` (formata stderr do FFmpeg) |
|
||||
| File Adapter | `FilePickerAdapter` |
|
||||
| Tipo | Exemplos |
|
||||
| ------------ | --------------------------------------------------------- |
|
||||
| Gateway | `FfmpegCommandBuilder`, `FfmpegGateway`, `FfprobeGateway` |
|
||||
| Presenter | `ErrorPresenter` (formata stderr do FFmpeg) |
|
||||
| File Adapter | `FilePickerAdapter` |
|
||||
|
||||
> **`FfprobeGateway`** implementa `MediaInfoPort`. Executa `ffprobe -v quiet -print_format json -show_streams` e mapeia a saída para `Vec<MediaTrackInfo>`. Não conhece o domínio além das structs que está populando.
|
||||
>
|
||||
@@ -267,11 +278,11 @@ Implementam os ports definidos na camada de Application. Traduzem dados entre o
|
||||
|
||||
Camada mais externa. Contém o framework de UI e a execução real de processos.
|
||||
|
||||
| Tipo | Exemplos |
|
||||
|--------------|-------------------------------------------------------|
|
||||
| UI | `App` (eframe), componentes egui |
|
||||
| Process | Execução de `std::process::Command` / `tokio::process`|
|
||||
| Filesystem | Leitura e escrita de arquivos |
|
||||
| Tipo | Exemplos |
|
||||
| ---------- | ------------------------------------------------------ |
|
||||
| UI | `App` (eframe), componentes egui |
|
||||
| Process | Execução de `std::process::Command` / `tokio::process` |
|
||||
| Filesystem | Leitura e escrita de arquivos |
|
||||
|
||||
---
|
||||
|
||||
@@ -300,14 +311,14 @@ src/
|
||||
|
||||
## 10. Débitos Técnicos
|
||||
|
||||
| ID | Descrição | Impacto | Mitigação |
|
||||
|-----|--------------------------------------|------------------|--------------------------------------|
|
||||
| DT-01 | FFmpeg não embutido | Usuário precisa instalar | Distribuir junto com a aplicação |
|
||||
| DT-02 | Dependência de processo externo | Menor controle interno | Encapsular via módulo de serviço |
|
||||
| DT-03 | Parsing de erros do FFmpeg (stderr) | Necessário tratamento manual | Parsear saída e exibir mensagem amigável |
|
||||
| DT-04 | Compatibilidade de codecs | Alguns codecs podem não ser aceitos | Usar MKV como container padrão |
|
||||
| DT-05 | Performance de processo externo | Pequeno overhead | Aceitável — mux é rápido |
|
||||
| DT-06 | ffprobe como dependência adicional | Parsing de JSON da saída do ffprobe | Validar presença de ffprobe na inicialização; exibir mensagem clara se ausente |
|
||||
| ID | Descrição | Impacto | Mitigação |
|
||||
| ----- | ----------------------------------- | ----------------------------------- | ------------------------------------------------------------------------------ |
|
||||
| DT-01 | FFmpeg não embutido | Usuário precisa instalar | Distribuir junto com a aplicação |
|
||||
| DT-02 | Dependência de processo externo | Menor controle interno | Encapsular via módulo de serviço |
|
||||
| DT-03 | Parsing de erros do FFmpeg (stderr) | Necessário tratamento manual | Parsear saída e exibir mensagem amigável |
|
||||
| DT-04 | Compatibilidade de codecs | Alguns codecs podem não ser aceitos | Usar MKV como container padrão |
|
||||
| DT-05 | Performance de processo externo | Pequeno overhead | Aceitável — mux é rápido |
|
||||
| DT-06 | ffprobe como dependência adicional | Parsing de JSON da saída do ffprobe | Validar presença de ffprobe na inicialização; exibir mensagem clara se ausente |
|
||||
|
||||
---
|
||||
|
||||
@@ -318,7 +329,6 @@ src/
|
||||
- Seleção de faixa padrão no container MKV
|
||||
- Remoção de faixas existentes do arquivo original
|
||||
- Suporte a perfis de configuração salvos
|
||||
- Modo de processamento em lote (batch)
|
||||
|
||||
---
|
||||
|
||||
@@ -345,18 +355,18 @@ src/
|
||||
|
||||
O FFmpeg é uma ferramenta de poder absurdo — e opacidade equivalente. O usuário não entende `track index`, `stream mapping` ou `itsoffset`. O usuário entende:
|
||||
|
||||
- *"Áudio em português está 1.2 segundos atrasado"*
|
||||
- *"Quero adicionar a legenda em inglês"*
|
||||
- *"Gerar o arquivo final"*
|
||||
- _"Áudio em português está 1.2 segundos atrasado"_
|
||||
- _"Quero adicionar a legenda em inglês"_
|
||||
- _"Gerar o arquivo final"_
|
||||
|
||||
Toda decisão de UX deve partir dessa perspectiva. Termos técnicos do FFmpeg nunca devem aparecer na interface.
|
||||
|
||||
| FFmpeg (interno) | Interface (usuário) |
|
||||
|-----------------------|--------------------------------------|
|
||||
| `-itsoffset -1200ms` | "Adiantar 1.2s" |
|
||||
| `stream 0:a:1` | "Faixa de áudio 2 — Português" |
|
||||
| `-c copy` | *(invisível — nunca exposto)* |
|
||||
| `ffprobe output` | Lista de faixas detectadas |
|
||||
| FFmpeg (interno) | Interface (usuário) |
|
||||
| -------------------- | ------------------------------ |
|
||||
| `-itsoffset -1200ms` | "Adiantar 1.2s" |
|
||||
| `stream 0:a:1` | "Faixa de áudio 2 — Português" |
|
||||
| `-c copy` | _(invisível — nunca exposto)_ |
|
||||
| `ffprobe output` | Lista de faixas detectadas |
|
||||
|
||||
---
|
||||
|
||||
@@ -373,6 +383,7 @@ O MKV (Matroska) é estruturalmente um banco de dados multimídia. Suas operaç
|
||||
O arquivo de saída não é uma criação nova — é uma nova **visão** do container original com faixas adicionadas e metadados ajustados, sem tocar nos bytes de mídia.
|
||||
|
||||
Esse modelo mental simplifica a implementação:
|
||||
|
||||
- Sem buffers de vídeo
|
||||
- Sem pipelines de transcoding
|
||||
- Apenas mapeamento de streams e metadados
|
||||
|
||||
Reference in New Issue
Block a user