# Fase 8 — Export por intervalo + locks

**Status:** concluída neste ambiente de desenvolvimento  
**Data:** 2026-08-19  
**URL:** https://vms.restor.app.br/exportacoes

## Contexto de desenvolvimento

Ainda **não há acesso às câmeras reais** (VLAN 192.168.20.x) nem HDD físico.  
Armazenamento = pastas locais `storage/disk01` e `storage/disk02` (mesmo filesystem).  
Validação com o **Simulador (lavfi)** e `php artisan ipcam:demo-clip`.

## Princípio

O operador pede **câmera + início + fim**. O sistema localiza segmentos em qualquer disco, corta (inclusive no meio do arquivo) e entrega um MP4.  
O caminho do disco e `relative_path` **não** aparecem na UI.

Enquanto o job corre, os originais ficam com **export lock**. A reciclagem (Fase 9) não deve apagá-los.

O arquivo exportado vai para `storage/app/exports/` (cache derivado), **não** para os discos de retenção.

## O que foi entregue

- Tabelas `export_jobs` e `export_locks`
- `ExportRunner`: overlap → lock → slice (`-ss`/`-t` após `-i`, `-c copy`, `-f mp4`) → concat se vários trechos
- FFmpeg só via argv (sem shell)
- UI no player (`/gravacoes/{camera}`) + lista `/exportacoes` + download autenticado
- Comando `php artisan ipcam:export {id}` (reprocessar um job)
- Comando `php artisan ipcam:demo-clip` para gerar ~20 s de lavfi no disco local
- Jobs curtos neste host rodam **síncronos** no POST (não há worker de queue)

## Aceite

| Critério | Resultado |
|---|---|
| Corte no meio do segmento | OK (teste 2 s–6 s de um clipe de 10 s) |
| Concat de 2 segmentos | OK |
| Download autenticado | OK |
| Export lock durante o job; some ao terminar | OK |
| UI/JSON sem `relative_path` / mount | OK |
| Sem `if fabricante` | OK |
| Sem câmera física / sem HDD | OK (lavfi + disk01 local) |

## Fora desta fase

Proteção/retenção (Fase 9 — concluída), eventos ONVIF, WebRTC.
