Skip to content

Commit a63e1d5

Browse files
feat: add resilient media process execution
1 parent 3b35732 commit a63e1d5

5 files changed

Lines changed: 304 additions & 49 deletions

File tree

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,19 @@ Para executar a auditoria localmente:
6868
npm run security:audit
6969
```
7070

71+
## Limites dos processos de mídia
72+
73+
As chamadas a FFmpeg e ffprobe possuem cancelamento por `AbortSignal`, limite de
74+
saída e timeout. Os defaults podem ser ajustados pelo ambiente:
75+
76+
- `FFMPEG_TIMEOUT_MS`: 30 minutos;
77+
- `FFPROBE_TIMEOUT_MS`: 60 segundos;
78+
- `MEDIA_PROCESS_MAX_BUFFER_BYTES`: 8 MiB por stream.
79+
80+
Timeouts são limitados a 6 horas e buffers a 64 MiB. O executor não usa shell,
81+
desabilita leitura interativa e retorna códigos distintos para cancelamento,
82+
timeout, excesso de saída e falha do processo.
83+
7184
## Formatos
7285

7386
- **Vertical (9:16)** — Shorts, Reels, TikTok

TODO.md

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1904,6 +1904,7 @@
19041904

19051905
- [ ] Extrair apenas primitives Remotion que aceitem `RenderInput` v2 sem ler banco/config global.
19061906
- [ ] Extrair pipeline FFmpeg atrás de recipes e jobs idempotentes.
1907+
- [x] Endurecer executor FFmpeg/ffprobe legado com timeout, cancelamento, limite de saída e erros tipados. Evidência: `MediaProcessError` e `tests/media/ffmpeg-service.integration.mjs`.
19071908
- [ ] Extrair transcription/timing atrás de adapter versionado.
19081909
- [ ] Extrair componentes de legenda atrás de `SubtitleStylePreset`.
19091910
- [ ] Extrair watchdog/progress para workflow base sem status ad hoc.
@@ -2373,7 +2374,7 @@ Pendências deliberadas:
23732374

23742375
### Slice F0-009 — Remoção do wrapper FFmpeg sem suporte
23752376

2376-
**Status:** concluído em 12 de julho de 2026; ainda não commitado.
2377+
**Status:** concluído e publicado em 12 de julho de 2026 no commit `3b35732`.
23772378

23782379
Entregas:
23792380

@@ -2411,10 +2412,40 @@ Incidente do primeiro runner:
24112412
- o run `29213379388` do commit `3fb94db` falhou corretamente no typecheck porque `remotion/node_modules` não existia no runner limpo;
24122413
- a investigação revelou oito advisories no lockfile Remotion antigo, incluindo dois high;
24132414
- o gate local foi corrigido para instalar e auditar os dois lockfiles antes do typecheck e para empacotar o renderer explicitamente;
2414-
- a correção só poderá ser confirmada no runner hospedado depois da publicação deste slice.
2415+
- a correção foi confirmada no runner hospedado `29214156774`: todos os 19 passos concluíram com sucesso.
24152416

24162417
Pendências deliberadas:
24172418

24182419
- extrair recipes versionadas e execução idempotente pertence ao media worker v2;
2419-
- adicionar timeout, cancelamento e limites de stdout/stderr ao executor antes de aceitar jobs não confiáveis;
24202420
- fixar e registrar versões-alvo de FFmpeg/ffprobe em ADR próprio antes do primeiro ambiente de produção.
2421+
2422+
### Slice F0-010 — Executor seguro para processos de mídia
2423+
2424+
**Status:** concluído em 12 de julho de 2026; ainda não commitado.
2425+
2426+
Entregas:
2427+
2428+
- executor único para FFmpeg e ffprobe preservando `execFile` com `shell: false`;
2429+
- opções compatíveis e opcionais de `AbortSignal`, timeout e limite de buffer em todas as operações públicas do adapter;
2430+
- timeout default de 30 minutos para FFmpeg e 60 segundos para ffprobe, configuráveis por ambiente e limitados a 6 horas;
2431+
- limite default de 8 MiB por stream, configurável e limitado a 64 MiB;
2432+
- FFmpeg recebe `-nostdin`, `-nostats`, `-hide_banner` e log level mínimo por operação;
2433+
- erros tipados `MediaProcessError` com códigos separados para cancelamento, timeout, excesso de saída e falha operacional;
2434+
- mensagens estáveis não incluem command line, argumentos ou paths; somente a cauda limitada de stderr fica disponível para diagnóstico interno;
2435+
- chamadas existentes permanecem válidas porque o novo argumento de opções é opcional.
2436+
2437+
Evidências:
2438+
2439+
- integração real cobre cancelamento antes do spawn e durante encode ativo;
2440+
- timeout de ffprobe encerra o processo e retorna `MEDIA_PROCESS_TIMEOUT`;
2441+
- excesso de stderr retorna `MEDIA_PROCESS_OUTPUT_LIMIT` sem crescimento irrestrito;
2442+
- input inexistente retorna `MEDIA_PROCESS_FAILED` com stderr limitado a quatro mil caracteres;
2443+
- fluxo nominal continua cobrindo probe, normalize, proxy, áudio, silêncio/corte e thumbnail;
2444+
- teste de mídia passou três vezes consecutivas para reduzir risco de flakiness temporal.
2445+
2446+
Pendências deliberadas:
2447+
2448+
- cancelamento persistente entre processos/restarts pertence ao workflow durável e ao estado canônico de job;
2449+
- cleanup e lineage de outputs parciais devem ser definidos nas recipes idempotentes do media worker;
2450+
- cada recipe terá SLA próprio em vez de depender apenas do teto global;
2451+
- o presenter público deverá mapear códigos internos para erros estáveis sem expor stderr.

docs/adr/ADR-001-v2-modular-architecture.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,6 @@ renderer ◄── RenderInput materializado
4747
- Builds usam Webpack explicitamente enquanto os aliases de Remotion não forem migrados para Turbopack.
4848
- O adapter FFmpeg invoca `ffmpeg`/`ffprobe` com `execFile` e arrays de argumentos, sem shell ou wrapper abandonado.
4949
- `FFMPEG_PATH`/`FFPROBE_PATH` têm precedência; os binários empacotados são fallback e o `PATH` do worker é a última opção.
50+
- Todo processo de mídia usa timeout finito, `AbortSignal`, `maxBuffer`, `shell: false`, `-nostdin` e saída sem progresso interativo.
51+
- Falhas de processo são classificadas como cancelamento, timeout, limite de saída ou erro operacional; argumentos e paths não entram na mensagem pública.
5052
- Dependências públicas devem manter `npm audit` sem vulnerabilidades antes de exposição do produto.

0 commit comments

Comments
 (0)