Media — Video record, playback, screen-capture, formats (privacy + widgets)

mandatory

Contrato cross-surface para captura, playback e screen-capture de vídeo em apps Koder. Toggles de privacidade (`media.video.camera`, `media.video.screen`, `media.video.mic`) em Settings; defaults seguros (tudo OFF até prompt do SO); codecs canônicos (H.264/HEVC/AV1/VP9 in via kodec; H.264 + AAC out); widgets `KoderVideoPlayer` + `KoderVideoRecorder` + `KoderScreenCapture` em `engines/sdk/koder_kit`. Recording indicator obrigatório quando capture ativo. Upload size cap 500 MB. `<APP>-VIDEO-*` error map.

Media — Video Spec — v0.1

Normative cross-surface spec para video I/O em apps Koder. Implementação obrigatória via widgets KoderVideo* em engines/sdk/koder_kit (Flutter) e koder_web_kit (JS) — nunca rolar video_player upstream ou <video> raw local. Codec layer via engines/kodec (canônica) ou Koda port (shadow-active).


Scope

Aplica-se a *odo app Koder que grave, reproduza, ou faça screencapture de vídeo* call recording, tutorial inapp, attachment de vídeo em chat, demo em landing, screen-share em ferramenta de dev, upload de vídeo de produto.

Surfaces cobertas: Flutter mobile (Android + iOS), Flutter desktop (Linux + macOS + Windows), Flutter web ou templ+HTMX, TV (playback; gravação fora de escopo em TV). CLI/TUI exigem path arg + delegam ao desktop player externo.


1 — MUST: expose "Vídeo" toggle group in Settings

Sub-seção "Vídeo" do agrupamento "Mídia" em Settings; *eve*conter, na ordem:

  1. *âmera*(media.video.camera) — gate à camera
  2. *icrofone para vídeo*(media.video.mic) — gate ao mic durante gravação
  3. *ompartilhar tela*(media.video.screen) — gate ao screen-capture
  4. *esolução máxima*(media.video.max_height) — dropdown 480 / 720 / 1080 / 2160
  5. *ualidade*(media.video.bitrate_mbps) — slider 1-20 Mbps

Compartilha media.image.camera quando ambos coexistem (camera permission é granted ao app, não ao sub-uso); cada toggle controla *so* não permissão de SO.


2 — MUST: defaults seguros em fresh install

Chave Default Notas
media.video.camera *FF* Privacybydefault
media.video.mic *FF* Vídeo silencioso até user ativar
media.video.screen *FF* Screencapture nunca silenton; sempre exige toggle + prompt do SO
media.video.max_height 1080 Cap em 4K só se Settings.advanced ativo (raras as redes)
media.video.bitrate_mbps 5 5 Mbps casa com 1080p30 H.264 sem visible blocking

Quando qualquer toggle for OFF em runtime, o app *eve*parar qualquer capture ativo + liberar handles + dismiss screen-share dialog.


3 — MUST: privacidade + recording indicator

  • *UNCA*auto-upload de gravação (user confirma antes do POST)
  • *UNCA*screencapture em background sem uservisible indicator
  • *UNCA*keep camera open em background além de 5 s pós-leave
  • *ecording indicator*obrigatório: dot vermelho + timer + título

    da janela alterado para ● Recording — <app>; em mobile, system status bar fica vermelho (iOS) / mostra ícone (Android)

  • *XIF/metadata*strip equivalente para vídeo (camera serial, GPS

    de container MP4); media.video.strip_metadata = true default


4 — MUST: widget surface no koder_kit

Widget Função
KoderVideoPlayer Playback de KoderVideoRef ou URL; controls config (playpauseseekfullscreencaptions/speed)
KoderVideoRecorder Gravação com preview + start/stop + flip-camera; gates media.video.camera
KoderScreenCapture Screen share dialog + capture pipeline; gates media.video.screen; *orça*recording indicator
KoderVideoPicker Sheet "Gravar vídeo" / "Escolher da galeria"; retorna KoderVideoRef
KoderVideoThumbnail Frame thumbnail (default 1s mark) + lazy-load

KoderVideoRef: {uri, mime, durationMs, width, height, sizeBytes, hasAudio, codec, koderUserId?, workspaceId?}.


5 — MUST: format support

*ecode (via engines/kodec):*H.264, HEVC (HEIC pipeline), AV1, VP9 — container MP4, WebM, MOV.

*ncode (default):*H.264 + AAC + MP4 container. HEVC e AV1 são opt-in quando suportado pela surface (iOS encoder, browser MediaRecorder com codec hint).

*pload size cap:*500 MB pós-compress. Exceder → erro <APP>-VIDEO-SIZE-001 com sugestão de bitrate menor ou trim.

*ompression knob:*media.video.bitrate_mbps (§2) controla output; duração + resolução + bitrate determinam tamanho. App *eve*estimar size pré-encode e avisar se ultrapassar cap.


6 — MUST: error surface

Cenário ID Texto pt-BR
Permissão de câmera negada <APP>-VIDEO-CAM-001 "Permita o acesso à câmera para gravar vídeo."
Permissão de mic negada <APP>-VIDEO-MIC-001 "Permita o acesso ao microfone para vídeo com áudio."
Permissão de screen-capture negada <APP>-VIDEO-SCR-001 "Permita o compartilhamento de tela para continuar."
Codec não suportado pelo decoder local <APP>-VIDEO-CDC-001 "Este vídeo usa codec não suportado ($codec)."
Tamanho excede 500 MB <APP>-VIDEO-SIZE-001 "Vídeo muito grande. Reduza qualidade ou corte trechos."
Upload falhou <APP>-VIDEO-NET-001 "Falha ao enviar o vídeo. Tente novamente."
Encode falhou (kodec/hardware) <APP>-VIDEO-ENC-001 "Falha ao processar o vídeo. Tente novamente ou reduza qualidade."

7 — Observability

  • Counters: media.video.recorded, media.video.uploaded,

    media.video.upload_error, media.video.screen_captured

  • Latency histograms: media.video.encode_ms,

    media.video.upload_ms, media.video.first_frame_ms (playback)

  • *ão*emitir métricas que vazem conteúdo (transcript, frames,

    file path) — apenas counters + latência + dimensões anonimizadas (resolução, codec, duration)


8 — Adoption checklist (per app)

  • [ ] Importa KoderMediaSettingsTile (sub-seção Vídeo visível)
  • [ ] Usa KoderVideoPlayerKoderVideoRecorderKoderScreenCapture (nunca video_player upstream raw)
  • [ ] Defaults da §2 respeitados em fresh install
  • [ ] Recording indicator obrigatório (§3)
  • [ ] Codec layer via engines/kodec (ou Koda port quando flipped)
  • [ ] Error map da §6 implementado
  • [ ] Upload path respeita multi-tenancy/contract.kmd

Non-normative — referências

  • Sibling specs: specs/media/image.kmd (camera shared),

    specs/media/audio.kmd (mic + recording indicator paralelo), specs/media/document.kmd

  • Codec engine: engines/kodec/ (canônica, Rust); Koda port em

    engines/lang/koda/lib/{mp4,mp3,wav}.kd (shadow-active per Flipping Point em CLAUDE.md)

  • Implementation surface: engines/sdk/koder_kit/lib/src/media/
  • Voice precedent (mic + privacy contract): specs/voice/wake-word.kmd

Source: ../home/koder/dev/koder/meta/docs/stack/specs/media/video.kmd